Skip to content

📦 chore: Bump @librechat/agents to v3.1.56#12258

Merged
danny-avila merged 2 commits into
devfrom
chore/bump-agents-v3.1.56
Mar 16, 2026
Merged

📦 chore: Bump @librechat/agents to v3.1.56#12258
danny-avila merged 2 commits into
devfrom
chore/bump-agents-v3.1.56

Conversation

@danny-avila

@danny-avila danny-avila commented Mar 16, 2026

Copy link
Copy Markdown
Owner

@librechat/agents v3.1.55 → v3.1.56 — Change Summary

7 commits between the two tags (excluding the tag commits themselves), spanning March 8–16, 2026.


1. d3af1da — feat: Add CI Workflow for PRs

Files: .github/workflows/ci.yml (new, +179), publish.yml (+17/-19)

What changed: A brand-new GitHub Actions CI pipeline was created from scratch. It installs deps with node_modules caching, runs lint (eslint), type-checks (tsc --noEmit), runs core tests, and then conditionally runs integration test suites for Google/Anthropic LLMs and PTC/Tool Search only when files in those directories actually changed. The publish workflow was also cleaned up.

Why it matters: Before this, there was no automated CI on PRs. Code could land with type errors, lint violations, or broken tests without any automated gate. Now every PR runs the full quality pipeline, and expensive LLM integration tests only fire when relevant code changes.

Before: No CI on PRs. Publish workflow had no lint/type gate.
After: Full lint → type-check → test pipeline on every PR; conditional integration tests on directory-scoped changes.


2. 22831c0 — chore: Add ESLint + TypeScript Type-Checking to CI/Publish

Files: .github/workflows/ci.yml (+1/-1), publish.yml (+6)

What changed: A follow-up to the CI commit. Ensured the ESLint step in ci.yml was correctly scoped to TypeScript files in src/. Added tsc --noEmit to the publish workflow as a hard gate before building, so a type error cannot slip into a published npm package.

Why it matters: Prevents shipping broken TypeScript types to consumers of the @librechat/agents package.

Before: Publish could proceed with type errors.
After: Publish fails hard if TypeScript compilation fails.


3. 15b645c — refactor: Replace js-tiktoken with ai-tokenizer

Files: src/utils/tokens.ts (+43/-54), src/run.ts (+6/-2), package.json, package-lock.json, 8 scripts, 2 test files (new tokens.test.ts with 64 tests)

What changed: The legacy js-tiktoken dependency was dropped and replaced with ai-tokenizer. createTokenCounter in tokens.ts was refactored to use dynamic imports for encoding data (lazy loading), making initialization fully async. A TokenEncoderManager class was added with a reset() mechanism to clear cached tokenizers and free memory. src/run.ts was updated to properly await the async token counter. 64 new tests were added covering encoding correctness and memoization.

Why it matters: js-tiktoken uses WASM and has a large bundle footprint with a synchronous, eager-loading API. ai-tokenizer is lighter, uses dynamic imports for lazy loading, and supports a wider range of model encodings. The reset() mechanism on TokenEncoderManager directly addresses memory leaks in long-running server processes where tokenizers were cached indefinitely.

Before: Synchronous, WASM-based js-tiktoken loaded eagerly; no way to evict cached encoders.
After: ai-tokenizer with async, dynamic-import loading; TokenEncoderManager.reset() clears all cached tokenizers on demand.


4. ca4530f — fix: Preserve Image Blocks in ensureThinkingBlockInMessages (174× Token Amplification)

Files: src/messages/format.ts (+137/-34), src/messages/ensureThinkingBlock.test.ts (+484/-12), AGENTS.md (new), CLAUDE.md (new), eslint.config.mjs (+1)

What changed: A critical bug fix in ensureThinkingBlockInMessages. When the function needed to convert an AI→Tool sequence into a HumanMessage, it was calling getBufferString() on the message content, which serialized everything including base64-encoded image data into a plain text string. This was then fed back into the LLM as raw text.

The fix introduces several new helpers:

  • buildToolSequenceContent — constructs a structured content array from a tool-call sequence, keeping image blocks as native image_url/image blocks rather than serializing them.
  • appendMessageContent / flushTextChunks — handle the accumulation and flushing of text vs. binary content separately.
  • IMAGE_BLOCK_TYPES constant — an explicit allowlist of block types that contain binary image data, preventing them from being text-serialized.
  • isToolMessage — DRY helper for tool-role message detection.
  • Also prevents double-serialization of tool_calls when tool_use blocks are already present in content.

AGENTS.md and CLAUDE.md were added as project documentation files.

Why it matters: A single base64 image embedded in a tool sequence was being serialized to a multi-kilobyte string and re-sent as text on every subsequent turn. The commit message explicitly cites 174× token amplification — meaning one image could cause token usage to blow up nearly 200x, leading to context window exhaustion and enormous API costs.

Before: getBufferString() serialized image binary data into raw text strings, causing exponential token growth in multi-turn conversations involving images and tool calls.
After: Images are passed through as structured native blocks; text-only content is accumulated and flushed separately; no binary data touches the string serialization path.


5. 2e624be — fix: Only Process Trailing Sequence After Last HumanMessage

Files: src/messages/format.ts (+18/-10), src/messages/ensureThinkingBlock.test.ts (+20/-17)

What changed: A follow-up scoping fix to ensureThinkingBlockInMessages. Previously the function iterated the entire message array from index 0, applying the AI→Tool→HumanMessage conversion to every sequence in history that lacked a thinking block — including sequences that had already been sent and accepted in prior turns.

The fix: find the index of the last HumanMessage in the array, leave everything before it completely untouched, and only validate/convert the trailing AI→Tool sequence that is actually about to be sent to the provider.

Why it matters: The old behavior was re-processing and re-converting historical accepted context on every new turn. This had two concrete harms:

  1. Broke prompt caching — the provider's prompt cache keys changed every turn because historical messages were being mutated, so cache hits were impossible.
  2. Added unnecessary token overhead — previously-converted HumanMessages from prior turns were being re-created and potentially duplicated.

Before: Entire message history was re-scanned and mutated on every call; prompt caching was broken; token overhead grew with conversation length.
After: Only the trailing unvalidated sequence after the last HumanMessage is touched; all prior history is passed through verbatim; prompt caching works correctly.


6. 76260749 — feat: ToolCall Structure with auth and expires_at Fields

Files: src/stream.ts (+12), src/types/graph.ts (+2), src/types/stream.ts (+2)

What changed: Two new optional fields were added to the ToolCall data structures:

  • auth — authentication metadata for a tool call (likely OAuth tokens, API keys, or similar credentials needed to invoke the tool on behalf of a user).
  • expires_at — an expiration timestamp for the auth credential.

These were added to ToolCallDelta (the streaming type in stream.ts), PartMetadata (the graph-level type in graph.ts), and the stream types file. createContentAggregator was updated to propagate both fields through the streaming pipeline.

Why it matters: This is infrastructure for tool-call authentication flows — specifically to support scenarios where a tool requires a per-user auth token that has a finite TTL (e.g., OAuth access tokens, session tokens for code interpreters, or auth-gated MCP tools). Without these fields, the runtime had no way to carry auth context alongside the tool call itself or signal to the consumer that a credential has expired.

Before: ToolCallDelta and PartMetadata had no auth or expiration concept; auth had to be handled entirely out-of-band.
After: Auth credentials and expiration timestamps are first-class fields on ToolCall structures, propagated through the streaming content aggregator.


7. 6d2e7f7 — chore: npm audit fix

Files: package-lock.json (+11/-11)

What changed: Dependency lock file updated to resolve security vulnerabilities flagged by npm audit. No production code changed.

Why it matters: Keeps the published package's transitive dependency tree free of known CVEs.


Summary Table

# Commit Type Impact
1 Add CI workflow Infra Automated lint/type/test gate on all PRs
2 ESLint + tsc in CI/publish Infra Hard type-safety gate before publish
3 js-tiktokenai-tokenizer Refactor Lighter tokenizer, async loading, memory-safe reset
4 Fix 174× image token amplification Critical Fix Prevents catastrophic token blowup with images in tool sequences
5 Scope thinking-block fix to trailing sequence Fix Restores prompt caching correctness; eliminates wasted history mutations
6 auth + expires_at on ToolCall Feature Infrastructure for per-tool-call auth credential passing
7 npm audit fix Maintenance Security dependency hygiene

Copilot AI review requested due to automatic review settings March 16, 2026 03:34

Copilot AI 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.

Pull request overview

This PR bumps the backend dependency @librechat/agents from v3.1.55 to v3.1.56 across the backend workspaces and updates the root lockfile to match, keeping the monorepo’s runtime dependencies in sync.

Changes:

  • Update @librechat/agents version to ^3.1.56 in api/package.json and packages/api/package.json.
  • Update package-lock.json to resolve @librechat/agents@3.1.56 (including its updated dependency set).

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
packages/api/package.json Bumps @librechat/agents peer dependency to ^3.1.56 for the TS backend package.
api/package.json Bumps @librechat/agents dependency to ^3.1.56 for the legacy backend workspace.
package-lock.json Updates resolved @librechat/agents tarball/integrity and dependency graph to 3.1.56.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@danny-avila danny-avila merged commit 8271055 into dev Mar 16, 2026
9 checks passed
@danny-avila danny-avila deleted the chore/bump-agents-v3.1.56 branch March 16, 2026 03:51
jcbartle pushed a commit to jcbartle/LibreChat that referenced this pull request May 11, 2026
* 📦 chore: Bump `@librechat/agents` to v3.1.56

* chore: resolve type error, URL property check in isMCPDomainAllowed function
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