merge: complete @hanzochat fork + org/project/user switcher

Brings the fork completion (de-librechat, @hanzochat scope rename, @hanzo/iam
0.13 API) and the org/project/user switcher (validated active-org -> X-Org-Id
on both cloud seams) onto main for release.
This commit is contained in:
Hanzo Dev
2026-07-14 12:46:42 -07:00
1924 changed files with 6434 additions and 86389 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ services:
# - /var/run/docker.sock:/var/run/docker.sock
environment:
- HOST=0.0.0.0
- MONGO_URI=mongodb://mongodb:27017/LibreChat
- MONGO_URI=mongodb://mongodb:27017/Chat
# - OPENAI_REVERSE_PROXY=http://host.docker.internal:8070/v1
- MEILI_HOST=http://meilisearch:7700
+1 -1
View File
@@ -29,7 +29,7 @@ services:
gitnexus:
# Override via GITNEXUS_IMAGE in /opt/gitnexus/.env to use a fork or
# a pinned version tag like :v1.5.3 for reproducible rollbacks.
image: ${GITNEXUS_IMAGE:-ghcr.io/danny-avila/librechat-gitnexus:latest}
image: ${GITNEXUS_IMAGE:-ghcr.io/danny-avila/chat-gitnexus:latest}
container_name: gitnexus
restart: unless-stopped
networks:
+3 -3
View File
@@ -14,10 +14,10 @@ export NODE_OPTIONS="${NODE_OPTIONS:---max-old-space-size=1280}"
# metadata pointer without touching the index data.
#
# Registration failure handling:
# - main (LibreChat) and dev (LibreChat-dev) are critical. If either
# - main (Chat) and dev (Chat-dev) are critical. If either
# fails to register, exit 1 so docker marks the container unhealthy
# and the deploy workflow's readiness check surfaces the error.
# - PR indexes (LibreChat-pr-*) are best-effort. A corrupt PR index
# - PR indexes (Chat-pr-*) are best-effort. A corrupt PR index
# shouldn't take the whole server down.
if [ -d /indexes ]; then
for dir in /indexes/*/; do
@@ -27,7 +27,7 @@ if [ -d /indexes ]; then
echo "Registering index: $name"
if ! gitnexus index "$dir" --allow-non-git; then
case "$name" in
LibreChat|LibreChat-dev)
Chat|Chat-dev)
echo "ERROR: failed to register critical index $name" >&2
exit 1
;;
+5 -5
View File
@@ -484,7 +484,7 @@ ALLOW_PASSWORD_RESET=false
# server-side to the free model only and rejected from every other route.
ALLOW_GUEST_CHAT=false
# GUEST_MESSAGE_MAX=3 # free messages per IP before login is required
# GUEST_ENDPOINT=Hanzo # custom endpoint name from librechat.yaml (api.hanzo.ai)
# GUEST_ENDPOINT=Hanzo # custom endpoint name from chat.yaml (api.hanzo.ai)
# GUEST_MODEL=zen3-nano # free Zen model id guests are pinned to
# GUEST_TOKEN_EXPIRY=3600000 # guest JWT lifetime in ms (default 1h)
# GUEST_TOKEN_MAX=20 # max guest sessions issued per IP per window
@@ -775,7 +775,7 @@ HELP_AND_FAQ_URL=https://hanzo.ai/chat
# Use environment variable name for dynamic prefix (recommended for cloud deployments)
# REDIS_KEY_PREFIX_VAR=K_REVISION
# Or use static prefix directly
# REDIS_KEY_PREFIX=librechat
# REDIS_KEY_PREFIX=chat
# Redis connection limits
# REDIS_MAX_LISTENERS=40
@@ -839,8 +839,8 @@ OPENWEATHER_API_KEY=
# "Run Code" routes through the Hanzo unified backend (api.hanzo.ai/v1/exec),
# which executes in a Hanzo sandbox. execute_code POSTs {BASEURL}/exec with
# X-API-Key. https://hanzo.ai/docs/chat/code-interpreter
# LIBRECHAT_CODE_BASEURL=https://api.hanzo.ai/v1
# LIBRECHAT_CODE_API_KEY=your-key # prod: KMS chat-secrets/LIBRECHAT_CODE_API_KEY
# CHAT_CODE_BASEURL=https://api.hanzo.ai/v1
# CHAT_CODE_API_KEY=your-key # prod: KMS chat-secrets/CHAT_CODE_API_KEY
#======================#
# Web Search #
@@ -848,7 +848,7 @@ OPENWEATHER_API_KEY=
# Web Search routes through the Hanzo unified backend ONLY — no external SaaS.
# The searxng provider + firecrawl scraper both point at api.hanzo.ai/v1/websearch
# (Hanzo metasearch + Hanzo Crawl). See librechat.yaml `webSearch`.
# (Hanzo metasearch + Hanzo Crawl). See chat.yaml `webSearch`.
# https://hanzo.ai/docs/chat/features/web_search
# SEARXNG_INSTANCE_URL=https://api.hanzo.ai/v1/websearch
# FIRECRAWL_API_URL=https://api.hanzo.ai/v1/websearch
+20 -20
View File
@@ -1,10 +1,10 @@
#=====================================================================#
# LibreChat Configuration #
# Chat Configuration #
#=====================================================================#
# Please refer to the reference documentation for assistance #
# with configuring your LibreChat environment. #
# with configuring your Chat environment. #
# #
# https://www.librechat.ai/docs/configuration/dotenv #
# https://hanzo.ai/docs/chat/configuration/dotenv #
#=====================================================================#
#==================================================#
@@ -14,7 +14,7 @@
HOST=localhost
PORT=3080
MONGO_URI=mongodb://127.0.0.1:27017/LibreChat
MONGO_URI=mongodb://127.0.0.1:27017/Chat
DOMAIN_CLIENT=http://localhost:3080
DOMAIN_SERVER=http://localhost:3080
@@ -52,7 +52,7 @@ DEBUG_CONSOLE=false
#===============#
# Use an absolute path, a relative path, or a URL
# CONFIG_PATH="/alternative/path/to/librechat.yaml"
# CONFIG_PATH="/alternative/path/to/chat.yaml"
#===================================================#
# Endpoints #
@@ -63,9 +63,9 @@ DEBUG_CONSOLE=false
PROXY=
#===================================#
# Known Endpoints - librechat.yaml #
# Known Endpoints - chat.yaml #
#===================================#
# https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints
# https://hanzo.ai/docs/chat/configuration/chat_yaml/ai_endpoints
# ANYSCALE_API_KEY=
# APIPIE_API_KEY=
@@ -96,8 +96,8 @@ ANTHROPIC_API_KEY=user_provided
#============#
# Note: these variables are DEPRECATED
# Use the `librechat.yaml` configuration for `azureOpenAI` instead
# You may also continue to use them if you opt out of using the `librechat.yaml` configuration
# Use the `chat.yaml` configuration for `azureOpenAI` instead
# You may also continue to use them if you opt out of using the `chat.yaml` configuration
# AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated
# AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated
@@ -207,7 +207,7 @@ ASSISTANTS_API_KEY=user_provided
# The models for Azure Assistants are also determined by your Azure OpenAI configuration.
# More info, including how to enable use of Assistants with Azure here:
# https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints/azure#using-assistants-with-azure
# https://hanzo.ai/docs/chat/configuration/chat_yaml/ai_endpoints/azure#using-assistants-with-azure
#============#
# Plugins #
@@ -320,7 +320,7 @@ TTS_API_KEY=
#==================================================#
# RAG #
#==================================================#
# More info: https://www.librechat.ai/docs/configuration/rag_api
# More info: https://hanzo.ai/docs/chat/configuration/rag_api
# RAG_OPENAI_BASEURL=
# RAG_OPENAI_API_KEY=
@@ -513,7 +513,7 @@ EMAIL_ALLOW_SELFSIGNED=
EMAIL_USERNAME=
EMAIL_PASSWORD=
EMAIL_FROM_NAME=
EMAIL_FROM=noreply@librechat.ai
EMAIL_FROM=noreply@hanzo.ai
#========================#
# Mailgun API #
@@ -522,7 +522,7 @@ EMAIL_FROM=noreply@librechat.ai
# MAILGUN_API_KEY=your-mailgun-api-key
# MAILGUN_DOMAIN=mg.yourdomain.com
# EMAIL_FROM=noreply@yourdomain.com
# EMAIL_FROM_NAME="LibreChat"
# EMAIL_FROM_NAME="Chat"
# # Optional: For EU region
# MAILGUN_HOST=https://api.eu.mailgun.net
@@ -572,16 +572,16 @@ ALLOW_SHARED_LINKS_PUBLIC=true
# STATIC_CACHE_MAX_AGE=172800
# STATIC_CACHE_S_MAX_AGE=86400
# If you have another service in front of your LibreChat doing compression, disable express based compression here
# If you have another service in front of your Chat doing compression, disable express based compression here
# DISABLE_COMPRESSION=true
#===================================================#
# UI #
#===================================================#
APP_TITLE=LibreChat
APP_TITLE=Chat
# CUSTOM_FOOTER="My custom footer"
HELP_AND_FAQ_URL=https://librechat.ai
HELP_AND_FAQ_URL=https://hanzo.chat
# SHOW_BIRTHDAY_ICON=true
@@ -630,11 +630,11 @@ HELP_AND_FAQ_URL=https://librechat.ai
OPENWEATHER_API_KEY=
#====================================#
# LibreChat Code Interpreter API #
# Chat Code Interpreter API #
#====================================#
# https://code.librechat.ai
# LIBRECHAT_CODE_API_KEY=your-key
# https://code.hanzo.ai
# CHAT_CODE_API_KEY=your-key
#======================#
# Web Search #
@@ -644,7 +644,7 @@ OPENWEATHER_API_KEY=
# Omit values to allow user to provide them.
# For more information on configuration values, see:
# https://librechat.ai/docs/features/web_search
# https://hanzo.ai/docs/chat/features/web_search
# Search Provider (Required)
# SERPER_API_KEY=your_serper_api_key
+7 -7
View File
@@ -6,15 +6,15 @@ OPENAI_API_KEY=sk-hanzo-your-api-key-here
OPENAI_BASE_URL=https://api.hanzo.ai/v1
# Code Interpreter ("Run Code") — Hanzo unified backend.
# LibreChat's execute_code tool POSTs {LIBRECHAT_CODE_BASEURL}/exec with header
# Chat's execute_code tool POSTs {CHAT_CODE_BASEURL}/exec with header
# X-API-Key. cloud-api serves /v1/exec (-> sandboxed executor). The key is
# KMS-sourced (chat-secrets/LIBRECHAT_CODE_API_KEY). These are the ONLY vars
# LibreChat reads — the old CODE_EXECUTION_ENDPOINT/RUNTIME_API_KEY were dead.
LIBRECHAT_CODE_BASEURL=https://api.hanzo.ai/v1
LIBRECHAT_CODE_API_KEY=set-in-KMS-chat-secrets
# KMS-sourced (chat-secrets/CHAT_CODE_API_KEY). These are the ONLY vars
# Chat reads — the old CODE_EXECUTION_ENDPOINT/RUNTIME_API_KEY were dead.
CHAT_CODE_BASEURL=https://api.hanzo.ai/v1
CHAT_CODE_API_KEY=set-in-KMS-chat-secrets
# Web Search — Hanzo unified backend (searxng + firecrawl compat over Hanzo
# search + crawl). See librechat.yaml `webSearch`. One shared service key.
# search + crawl). See chat.yaml `webSearch`. One shared service key.
SEARXNG_INSTANCE_URL=https://api.hanzo.ai/v1/websearch
FIRECRAWL_API_URL=https://api.hanzo.ai/v1/websearch
WEBSEARCH_API_KEY=set-in-KMS-chat-secrets
@@ -85,5 +85,5 @@ DEBUG_LOGGING=false
# ====== NOTES ======
# 1. Get your Hanzo API key from https://hanzo.ai/dashboard
# 2. All AI providers are accessed through api.hanzo.ai -- no individual keys needed
# 3. Model list is configured in librechat.yaml under endpoints.custom (Hanzo endpoint)
# 3. Model list is configured in chat.yaml under endpoints.custom (Hanzo endpoint)
# 4. zen4 is the default model for new conversations
+1 -1
View File
@@ -38,7 +38,7 @@ Project maintainers have the right and responsibility to remove, edit, or reject
- Install [MongoDB Community Edition](https://www.mongodb.com/docs/manual/administration/install-community/), ensure that `mongosh` connects to your local instance.
- Run: `npx install playwright`, then `npx playwright install`.
- Copy `config.local`: `cp e2e/config.local.example.ts e2e/config.local.ts`.
- Copy `librechat.yaml`: `cp librechat.example.yaml librechat.yaml`.
- Copy `chat.yaml`: `cp chat.example.yaml chat.yaml`.
- Run: `npm run e2e`.
## 2. Development Notes
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
CHART_PATH="${CHART_PATH:-helm/librechat/Chart.yaml}"
CHART_PATH="${CHART_PATH:-helm/chat/Chart.yaml}"
DEFAULT_BRANCH="${DEFAULT_BRANCH:-main}"
BASE_REF="${BASE_REF:-refs/remotes/origin/${DEFAULT_BRANCH}}"
BACKFILL_FROM_VERSION="${BACKFILL_FROM_VERSION:-1.9.0}"
+3 -3
View File
@@ -67,11 +67,11 @@ jobs:
- name: Run unit tests
run: cd api && pnpm run test:ci
- name: Run librechat-data-provider unit tests
- name: Run @hanzochat/data-provider unit tests
run: cd packages/data-provider && pnpm run test:ci
- name: Run @librechat/data-schemas unit tests
- name: Run @hanzochat/data-schemas unit tests
run: cd packages/data-schemas && pnpm run test:ci
- name: Run @librechat/api unit tests
- name: Run @hanzochat/api unit tests
run: cd packages/api && pnpm run test:ci
+2 -2
View File
@@ -1,4 +1,4 @@
name: Publish `@librechat/client` to NPM
name: Publish `@hanzochat/client` to NPM
on:
push:
@@ -47,7 +47,7 @@ jobs:
working-directory: packages/client
run: |
PACKAGE_VERSION=$(node -p "require('./package.json').version")
PUBLISHED_VERSION=$(npm view @librechat/client version 2>/dev/null || echo "0.0.0")
PUBLISHED_VERSION=$(npm view @hanzochat/client version 2>/dev/null || echo "0.0.0")
if [ "$PACKAGE_VERSION" = "$PUBLISHED_VERSION" ]; then
echo "No version change, skipping publish"
echo "skip=true" >> $GITHUB_OUTPUT
+1 -1
View File
@@ -1,4 +1,4 @@
name: Publish `librechat-data-provider` to NPM
name: Publish `@hanzochat/data-provider` to NPM
on:
push:
+2 -2
View File
@@ -1,4 +1,4 @@
name: Publish `@librechat/data-schemas` to NPM
name: Publish `@hanzochat/data-schemas` to NPM
on:
push:
@@ -47,7 +47,7 @@ jobs:
working-directory: packages/data-schemas
run: |
PACKAGE_VERSION=$(node -p "require('./package.json').version")
PUBLISHED_VERSION=$(npm view @librechat/data-schemas version 2>/dev/null || echo "0.0.0")
PUBLISHED_VERSION=$(npm view @hanzochat/data-schemas version 2>/dev/null || echo "0.0.0")
if [ "$PACKAGE_VERSION" = "$PUBLISHED_VERSION" ]; then
echo "No version change, skipping publish"
echo "skip=true" >> $GITHUB_OUTPUT
+3 -3
View File
@@ -14,7 +14,7 @@ jobs:
deploy:
runs-on: hanzo-deploy-linux-amd64
if: |
github.repository == 'danny-avila/LibreChat' &&
github.repository == 'danny-avila/Chat' &&
(github.event_name == 'workflow_dispatch' ||
(github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'dev'))
steps:
@@ -34,10 +34,10 @@ jobs:
run: |
ssh ${DO_USER}@${DO_HOST} << EOF
sudo -i -u danny bash << 'EEOF'
cd ~/LibreChat && \
cd ~/Chat && \
git fetch origin main && \
sudo npm run stop:deployed && \
sudo docker images --format "{{.Repository}}:{{.ID}}" | grep -E "lc-dev|librechat" | cut -d: -f2 | xargs -r sudo docker rmi -f || true && \
sudo docker images --format "{{.Repository}}:{{.ID}}" | grep -E "lc-dev|chat" | cut -d: -f2 | xargs -r sudo docker rmi -f || true && \
sudo npm run update:deployed && \
git checkout dev && \
git pull origin dev && \
+2 -2
View File
@@ -27,10 +27,10 @@ jobs:
include:
- target: api-build
file: Dockerfile.multi
image_name: librechat-dev-api
image_name: chat-dev-api
- target: node
file: Dockerfile
image_name: librechat-dev
image_name: chat-dev
steps:
# Check out the repository
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
NODE_ENV: CI
SEARCH: false
MONGO_URI: mongodb://localhost:27017/librechat-test
MONGO_URI: mongodb://localhost:27017/chat-test
JWT_SECRET: e2e-test-jwt-secret
JWT_REFRESH_SECRET: e2e-test-jwt-refresh-secret
CREDS_KEY: e2e-test-creds-key-32chars00000000
+1 -1
View File
@@ -74,7 +74,7 @@ jobs:
run: |
ssh -i ~/.ssh/deploy_key "$SSH_USER@$SSH_HOST" PR_NUM="$PR_NUM" bash <<'REMOTE'
set -e
TARGET="/opt/gitnexus/indexes/LibreChat-pr-$PR_NUM"
TARGET="/opt/gitnexus/indexes/Chat-pr-$PR_NUM"
if [ -d "$TARGET" ]; then
echo "Removing $TARGET"
rm -rf "$TARGET"
+11 -11
View File
@@ -71,7 +71,7 @@ permissions:
# cancel-in-progress so rapid pushes to the same ref coalesced but deploys
# targeting different refs ran in parallel. That had a data race: the
# prune-stale-indexes step computes its active_names up front, so if
# deploy A is rsyncing /opt/gitnexus/indexes/LibreChat-pr-12580 while
# deploy A is rsyncing /opt/gitnexus/indexes/Chat-pr-12580 while
# deploy B (started slightly later with a different ref) prunes, B can
# rm -rf a folder A is still uploading into.
#
@@ -85,7 +85,7 @@ concurrency:
env:
GITNEXUS_VERSION: '1.5.3'
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/librechat-gitnexus
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/chat-gitnexus
jobs:
# Rebuilds the long-lived image only when Dockerfile/entrypoint/extensions
@@ -200,8 +200,8 @@ jobs:
// --- main and dev branches ---
for (const [branch, name] of [
['main', 'LibreChat'],
['dev', 'LibreChat-dev'],
['main', 'Chat'],
['dev', 'Chat-dev'],
]) {
const artifactName = `gitnexus-index-${branch}`;
const fresh = await latestArtifact(artifactName);
@@ -260,11 +260,11 @@ jobs:
for (const { pr, artifactName, fresh } of keptPrs) {
serve.push({
name: `LibreChat-pr-${pr.number}`,
name: `Chat-pr-${pr.number}`,
artifactName,
runId: fresh.workflow_run.id,
});
core.info(`PR #${pr.number}: run ${fresh.workflow_run.id} -> LibreChat-pr-${pr.number}`);
core.info(`PR #${pr.number}: run ${fresh.workflow_run.id} -> Chat-pr-${pr.number}`);
}
if (evictedPrs.length) {
core.info(
@@ -305,7 +305,7 @@ jobs:
--name "$artifact" \
--dir "$target"; then
case "$name" in
LibreChat|LibreChat-dev)
Chat|Chat-dev)
echo "::error::Failed to download critical artifact $artifact"
exit 1
;;
@@ -438,7 +438,7 @@ jobs:
# is visible and the container isn't restarted with stale
# or missing data. PR indexes are best-effort.
case "$name" in
LibreChat|LibreChat-dev)
Chat|Chat-dev)
echo "::error::rsync failed for critical index $name — aborting deploy"
exit 1
;;
@@ -566,10 +566,10 @@ jobs:
const matrix = JSON.parse(process.env.MATRIX || '[]');
const triggerRunId = Number(process.env.TRIGGER_RUN_ID);
const match = matrix.find(
(m) => m.runId === triggerRunId && m.name.startsWith('LibreChat-pr-'),
(m) => m.runId === triggerRunId && m.name.startsWith('Chat-pr-'),
);
if (match) {
prNum = parseInt(match.name.replace('LibreChat-pr-', ''), 10);
prNum = parseInt(match.name.replace('Chat-pr-', ''), 10);
}
}
@@ -584,7 +584,7 @@ jobs:
`### GitNexus: ${ok ? '🚀 deployed' : '❌ deploy failed'}`,
'',
ok
? `The \`LibreChat-pr-${prNum}\` index is now live on the MCP server.`
? `The \`Chat-pr-${prNum}\` index is now live on the MCP server.`
: `The deploy failed — the previous index (if any) continues to be served.`,
`[Deploy run](${deployUrl})`,
].join('\n');
+12 -12
View File
@@ -30,9 +30,9 @@ jobs:
- name: Build Subchart Deps
run: |
cd helm/librechat
cd helm/chat
helm dependency build
cd ../librechat-rag-api
cd ../chat-rag-api
helm dependency build
- name: Get Chart Version
@@ -50,26 +50,26 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
# Run Helm OCI Charts Releaser
# This is for the librechat chart
- name: Release Helm OCI Charts for librechat
# This is for the chat chart
- name: Release Helm OCI Charts for chat
uses: appany/helm-oci-chart-releaser@v0.5.0
with:
name: librechat
repository: ${{ github.actor }}/librechat-chart
name: chat
repository: ${{ github.actor }}/chat-chart
tag: ${{ steps.chart-version.outputs.CHART_VERSION }}
path: helm/librechat
path: helm/chat
registry: ghcr.io
registry_username: ${{ github.actor }}
registry_password: ${{ secrets.GITHUB_TOKEN }}
# this is for the librechat-rag-api chart
- name: Release Helm OCI Charts for librechat-rag-api
# this is for the chat-rag-api chart
- name: Release Helm OCI Charts for chat-rag-api
uses: appany/helm-oci-chart-releaser@v0.5.0
with:
name: librechat-rag-api
repository: ${{ github.actor }}/librechat-chart
name: chat-rag-api
repository: ${{ github.actor }}/chat-chart
tag: ${{ steps.chart-version.outputs.CHART_VERSION }}
path: helm/librechat-rag-api
path: helm/chat-rag-api
registry: ghcr.io
registry_username: ${{ github.actor }}
registry_password: ${{ secrets.GITHUB_TOKEN }}
+2 -2
View File
@@ -15,10 +15,10 @@ jobs:
include:
- target: api-build
file: Dockerfile.multi
image_name: librechat-api
image_name: chat-api
- target: node
file: Dockerfile
image_name: librechat
image_name: chat
steps:
- name: Checkout
+2 -2
View File
@@ -39,14 +39,14 @@ jobs:
env:
BASE_REF: refs/remotes/origin/main
BACKFILL_FROM_VERSION: 1.9.0
CHART_PATH: helm/librechat/Chart.yaml
CHART_PATH: helm/chat/Chart.yaml
DEFAULT_BRANCH: main
DISPATCH_WORKFLOW: helmcharts.yml
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
RELEASE_EXISTING_TAG: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.release_existing_tag || '' }}
REPO_DIR: /tmp/librechat-sync
REPO_DIR: /tmp/chat-sync
TAG_PREFIX: chart-
steps:
- name: Fetch main and tags
+2 -2
View File
@@ -17,10 +17,10 @@ jobs:
include:
- target: api-build
file: Dockerfile.multi
image_name: librechat-api
image_name: chat-api
- target: node
file: Dockerfile
image_name: librechat
image_name: chat
steps:
# Check out the repository
+1 -1
View File
@@ -68,7 +68,7 @@ jobs:
run: pnpm run test:api
env:
NODE_ENV: test
MONGO_URI: mongodb://localhost:27017/librechat-test
MONGO_URI: mongodb://localhost:27017/chat-test
MEILI_HOST: http://localhost:7700
MEILI_MASTER_KEY: test_master_key
+28 -28
View File
@@ -117,52 +117,52 @@ jobs:
extract_deps_from_code "packages/client" packages_client_used_code.txt
extract_deps_from_code "packages/api" packages_api_used_code.txt
- name: Get @librechat/client dependencies
id: get-librechat-client-deps
- name: Get @hanzochat/client dependencies
id: get-chat-client-deps
run: |
if [[ -f "packages/client/package.json" ]]; then
# Get all dependencies from @librechat/client (dependencies, devDependencies, and peerDependencies)
# Get all dependencies from @hanzochat/client (dependencies, devDependencies, and peerDependencies)
DEPS=$(jq -r '.dependencies // {} | keys[]' packages/client/package.json 2>/dev/null || echo "")
DEV_DEPS=$(jq -r '.devDependencies // {} | keys[]' packages/client/package.json 2>/dev/null || echo "")
PEER_DEPS=$(jq -r '.peerDependencies // {} | keys[]' packages/client/package.json 2>/dev/null || echo "")
# Combine all dependencies
echo "$DEPS" > librechat_client_deps.txt
echo "$DEV_DEPS" >> librechat_client_deps.txt
echo "$PEER_DEPS" >> librechat_client_deps.txt
echo "$DEPS" > chat_client_deps.txt
echo "$DEV_DEPS" >> chat_client_deps.txt
echo "$PEER_DEPS" >> chat_client_deps.txt
# Also include dependencies that are imported in packages/client
cat packages_client_used_code.txt >> librechat_client_deps.txt
cat packages_client_used_code.txt >> chat_client_deps.txt
# Remove empty lines and sort
grep -v '^$' librechat_client_deps.txt | sort -u > temp_deps.txt
mv temp_deps.txt librechat_client_deps.txt
grep -v '^$' chat_client_deps.txt | sort -u > temp_deps.txt
mv temp_deps.txt chat_client_deps.txt
else
touch librechat_client_deps.txt
touch chat_client_deps.txt
fi
- name: Get @librechat/api dependencies
id: get-librechat-api-deps
- name: Get @hanzochat/api dependencies
id: get-chat-api-deps
run: |
if [[ -f "packages/api/package.json" ]]; then
# Get all dependencies from @librechat/api (dependencies, devDependencies, and peerDependencies)
# Get all dependencies from @hanzochat/api (dependencies, devDependencies, and peerDependencies)
DEPS=$(jq -r '.dependencies // {} | keys[]' packages/api/package.json 2>/dev/null || echo "")
DEV_DEPS=$(jq -r '.devDependencies // {} | keys[]' packages/api/package.json 2>/dev/null || echo "")
PEER_DEPS=$(jq -r '.peerDependencies // {} | keys[]' packages/api/package.json 2>/dev/null || echo "")
# Combine all dependencies
echo "$DEPS" > librechat_api_deps.txt
echo "$DEV_DEPS" >> librechat_api_deps.txt
echo "$PEER_DEPS" >> librechat_api_deps.txt
echo "$DEPS" > chat_api_deps.txt
echo "$DEV_DEPS" >> chat_api_deps.txt
echo "$PEER_DEPS" >> chat_api_deps.txt
# Also include dependencies that are imported in packages/api
cat packages_api_used_code.txt >> librechat_api_deps.txt
cat packages_api_used_code.txt >> chat_api_deps.txt
# Remove empty lines and sort
grep -v '^$' librechat_api_deps.txt | sort -u > temp_deps.txt
mv temp_deps.txt librechat_api_deps.txt
grep -v '^$' chat_api_deps.txt | sort -u > temp_deps.txt
mv temp_deps.txt chat_api_deps.txt
else
touch librechat_api_deps.txt
touch chat_api_deps.txt
fi
- name: Extract Workspace Dependencies
@@ -173,14 +173,14 @@ jobs:
local package_json=$1
local output_file=$2
# Get all workspace dependencies (starting with @librechat/)
# Get all workspace dependencies (starting with @hanzochat/)
if [[ -f "$package_json" ]]; then
local workspace_deps=$(jq -r '.dependencies // {} | to_entries[] | select(.key | startswith("@librechat/")) | .key' "$package_json" 2>/dev/null || echo "")
local workspace_deps=$(jq -r '.dependencies // {} | to_entries[] | select(.key | startswith("@hanzochat/")) | .key' "$package_json" 2>/dev/null || echo "")
# For each workspace dependency, get its dependencies
for dep in $workspace_deps; do
# Convert @librechat/api to packages/api
local workspace_path=$(echo "$dep" | sed 's/@librechat\//packages\//')
# Convert @hanzochat/api to packages/api
local workspace_path=$(echo "$dep" | sed 's/@chat\//packages\//')
local workspace_package_json="${workspace_path}/package.json"
if [[ -f "$workspace_package_json" ]]; then
@@ -223,8 +223,8 @@ jobs:
chmod -R 755 client
cd client
UNUSED=$(depcheck --json | jq -r '.dependencies | join("\n")' || echo "")
# Exclude dependencies used in scripts, code, workspace packages, and @librechat/client imports
UNUSED=$(comm -23 <(echo "$UNUSED" | sort) <(cat ../client_used_deps.txt ../client_used_code.txt ../client_workspace_deps.txt ../packages_client_used_code.txt ../librechat_client_deps.txt 2>/dev/null | sort -u) || echo "")
# Exclude dependencies used in scripts, code, workspace packages, and @hanzochat/client imports
UNUSED=$(comm -23 <(echo "$UNUSED" | sort) <(cat ../client_used_deps.txt ../client_used_code.txt ../client_workspace_deps.txt ../packages_client_used_code.txt ../chat_client_deps.txt 2>/dev/null | sort -u) || echo "")
# Filter out false positives
UNUSED=$(echo "$UNUSED" | grep -v "^micromark-extension-llm-math$" || echo "")
echo "CLIENT_UNUSED<<EOF" >> $GITHUB_ENV
@@ -240,8 +240,8 @@ jobs:
chmod -R 755 api
cd api
UNUSED=$(depcheck --json | jq -r '.dependencies | join("\n")' || echo "")
# Exclude dependencies used in scripts, code, workspace packages, and @librechat/api imports
UNUSED=$(comm -23 <(echo "$UNUSED" | sort) <(cat ../api_used_deps.txt ../api_used_code.txt ../api_workspace_deps.txt ../packages_api_used_code.txt ../librechat_api_deps.txt 2>/dev/null | sort -u) || echo "")
# Exclude dependencies used in scripts, code, workspace packages, and @hanzochat/api imports
UNUSED=$(comm -23 <(echo "$UNUSED" | sort) <(cat ../api_used_deps.txt ../api_used_code.txt ../api_workspace_deps.txt ../packages_api_used_code.txt ../chat_api_deps.txt 2>/dev/null | sort -u) || echo "")
echo "API_UNUSED<<EOF" >> $GITHUB_ENV
echo "$UNUSED" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
+3 -3
View File
@@ -121,12 +121,12 @@ docker-compose.override.yml
dump.rdb
helm/**/.values.yaml
helm/**/charts/
helm/librechat/Chart.lock
helm/chat/Chart.lock
hive-mind-prompt-*.txt
junit.xml
lib-cov
librechat.yaml
librechat.yml
chat.yaml
chat.yml
logs
meili_data*
meili_data/
+166 -166
View File
@@ -11,41 +11,41 @@ All notable changes to this project will be documented in this file.
### ✨ New Features
- ✨ feat: implement search parameter updates by **@mawburn** in [#7151](https://github.com/danny-avila/LibreChat/pull/7151)
- 🎏 feat: Add MCP support for Streamable HTTP Transport by **@benverhees** in [#7353](https://github.com/danny-avila/LibreChat/pull/7353)
- 🔒 feat: Add Content Security Policy using Helmet middleware by **@rubentalstra** in [#7377](https://github.com/danny-avila/LibreChat/pull/7377)
- ✨ feat: Add Normalization for MCP Server Names by **@danny-avila** in [#7421](https://github.com/danny-avila/LibreChat/pull/7421)
- 📊 feat: Improve Helm Chart by **@hofq** in [#3638](https://github.com/danny-avila/LibreChat/pull/3638)
- 🦾 feat: Claude-4 Support by **@danny-avila** in [#7509](https://github.com/danny-avila/LibreChat/pull/7509)
- 🪨 feat: Bedrock Support for Claude-4 Reasoning by **@danny-avila** in [#7517](https://github.com/danny-avila/LibreChat/pull/7517)
- ✨ feat: implement search parameter updates by **@mawburn** in [#7151](https://github.com/danny-avila/Chat/pull/7151)
- 🎏 feat: Add MCP support for Streamable HTTP Transport by **@benverhees** in [#7353](https://github.com/danny-avila/Chat/pull/7353)
- 🔒 feat: Add Content Security Policy using Helmet middleware by **@rubentalstra** in [#7377](https://github.com/danny-avila/Chat/pull/7377)
- ✨ feat: Add Normalization for MCP Server Names by **@danny-avila** in [#7421](https://github.com/danny-avila/Chat/pull/7421)
- 📊 feat: Improve Helm Chart by **@hofq** in [#3638](https://github.com/danny-avila/Chat/pull/3638)
- 🦾 feat: Claude-4 Support by **@danny-avila** in [#7509](https://github.com/danny-avila/Chat/pull/7509)
- 🪨 feat: Bedrock Support for Claude-4 Reasoning by **@danny-avila** in [#7517](https://github.com/danny-avila/Chat/pull/7517)
### 🌍 Internationalization
- 🌍 i18n: Add `Danish` and `Czech` and `Catalan` localization support by **@rubentalstra** in [#7373](https://github.com/danny-avila/LibreChat/pull/7373)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7375](https://github.com/danny-avila/LibreChat/pull/7375)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7468](https://github.com/danny-avila/LibreChat/pull/7468)
- 🌍 i18n: Add `Danish` and `Czech` and `Catalan` localization support by **@rubentalstra** in [#7373](https://github.com/danny-avila/Chat/pull/7373)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7375](https://github.com/danny-avila/Chat/pull/7375)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7468](https://github.com/danny-avila/Chat/pull/7468)
### 🔧 Fixes
- 💬 fix: update aria-label for accessibility in ConvoLink component by **@berry-13** in [#7320](https://github.com/danny-avila/LibreChat/pull/7320)
- 🔑 fix: use `apiKey` instead of `openAIApiKey` in OpenAI-like Config by **@danny-avila** in [#7337](https://github.com/danny-avila/LibreChat/pull/7337)
- 🔄 fix: update navigation logic in `useFocusChatEffect` to ensure correct search parameters are used by **@mawburn** in [#7340](https://github.com/danny-avila/LibreChat/pull/7340)
- 🔄 fix: Improve MCP Connection Cleanup by **@danny-avila** in [#7400](https://github.com/danny-avila/LibreChat/pull/7400)
- 🛡️ fix: Preset and Validation Logic for URL Query Params by **@danny-avila** in [#7407](https://github.com/danny-avila/LibreChat/pull/7407)
- 🌘 fix: artifact of preview text is illegible in dark mode by **@nhtruong** in [#7405](https://github.com/danny-avila/LibreChat/pull/7405)
- 🛡️ fix: Temporarily Remove CSP until Configurable by **@danny-avila** in [#7419](https://github.com/danny-avila/LibreChat/pull/7419)
- 💽 fix: Exclude index page `/` from static cache settings by **@sbruel** in [#7382](https://github.com/danny-avila/LibreChat/pull/7382)
- 💬 fix: update aria-label for accessibility in ConvoLink component by **@berry-13** in [#7320](https://github.com/danny-avila/Chat/pull/7320)
- 🔑 fix: use `apiKey` instead of `openAIApiKey` in OpenAI-like Config by **@danny-avila** in [#7337](https://github.com/danny-avila/Chat/pull/7337)
- 🔄 fix: update navigation logic in `useFocusChatEffect` to ensure correct search parameters are used by **@mawburn** in [#7340](https://github.com/danny-avila/Chat/pull/7340)
- 🔄 fix: Improve MCP Connection Cleanup by **@danny-avila** in [#7400](https://github.com/danny-avila/Chat/pull/7400)
- 🛡️ fix: Preset and Validation Logic for URL Query Params by **@danny-avila** in [#7407](https://github.com/danny-avila/Chat/pull/7407)
- 🌘 fix: artifact of preview text is illegible in dark mode by **@nhtruong** in [#7405](https://github.com/danny-avila/Chat/pull/7405)
- 🛡️ fix: Temporarily Remove CSP until Configurable by **@danny-avila** in [#7419](https://github.com/danny-avila/Chat/pull/7419)
- 💽 fix: Exclude index page `/` from static cache settings by **@sbruel** in [#7382](https://github.com/danny-avila/Chat/pull/7382)
### ⚙️ Other Changes
- 📜 docs: CHANGELOG for release v0.7.8 by **@github-actions[bot]** in [#7290](https://github.com/danny-avila/LibreChat/pull/7290)
- 📦 chore: Update API Package Dependencies by **@danny-avila** in [#7359](https://github.com/danny-avila/LibreChat/pull/7359)
- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7321](https://github.com/danny-avila/LibreChat/pull/7321)
- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7434](https://github.com/danny-avila/LibreChat/pull/7434)
- 🛡️ chore: `multer` v2.0.0 for CVE-2025-47935 and CVE-2025-47944 by **@danny-avila** in [#7454](https://github.com/danny-avila/LibreChat/pull/7454)
- 📂 refactor: Improve `FileAttachment` & File Form Deletion by **@danny-avila** in [#7471](https://github.com/danny-avila/LibreChat/pull/7471)
- 📊 chore: Remove Old Helm Chart by **@hofq** in [#7512](https://github.com/danny-avila/LibreChat/pull/7512)
- 🪖 chore: bump helm app version to v0.7.8 by **@austin-barrington** in [#7524](https://github.com/danny-avila/LibreChat/pull/7524)
- 📜 docs: CHANGELOG for release v0.7.8 by **@github-actions[bot]** in [#7290](https://github.com/danny-avila/Chat/pull/7290)
- 📦 chore: Update API Package Dependencies by **@danny-avila** in [#7359](https://github.com/danny-avila/Chat/pull/7359)
- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7321](https://github.com/danny-avila/Chat/pull/7321)
- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7434](https://github.com/danny-avila/Chat/pull/7434)
- 🛡️ chore: `multer` v2.0.0 for CVE-2025-47935 and CVE-2025-47944 by **@danny-avila** in [#7454](https://github.com/danny-avila/Chat/pull/7454)
- 📂 refactor: Improve `FileAttachment` & File Form Deletion by **@danny-avila** in [#7471](https://github.com/danny-avila/Chat/pull/7471)
- 📊 chore: Remove Old Helm Chart by **@hofq** in [#7512](https://github.com/danny-avila/Chat/pull/7512)
- 🪖 chore: bump helm app version to v0.7.8 by **@austin-barrington** in [#7524](https://github.com/danny-avila/Chat/pull/7524)
@@ -56,38 +56,38 @@ Changes from v0.7.8-rc1 to v0.7.8.
### ✨ New Features
- ✨ feat: Enhance form submission for touch screens by **@berry-13** in [#7198](https://github.com/danny-avila/LibreChat/pull/7198)
- 🔍 feat: Additional Tavily API Tool Parameters by **@glowforge-opensource** in [#7232](https://github.com/danny-avila/LibreChat/pull/7232)
- 🐋 feat: Add python to Dockerfile for increased MCP compatibility by **@technicalpickles** in [#7270](https://github.com/danny-avila/LibreChat/pull/7270)
- ✨ feat: Enhance form submission for touch screens by **@berry-13** in [#7198](https://github.com/danny-avila/Chat/pull/7198)
- 🔍 feat: Additional Tavily API Tool Parameters by **@glowforge-opensource** in [#7232](https://github.com/danny-avila/Chat/pull/7232)
- 🐋 feat: Add python to Dockerfile for increased MCP compatibility by **@technicalpickles** in [#7270](https://github.com/danny-avila/Chat/pull/7270)
### 🔧 Fixes
- 🔧 fix: Google Gemma Support & OpenAI Reasoning Instructions by **@danny-avila** in [#7196](https://github.com/danny-avila/LibreChat/pull/7196)
- 🛠️ fix: Conversation Navigation State by **@danny-avila** in [#7210](https://github.com/danny-avila/LibreChat/pull/7210)
- 🔄 fix: o-Series Model Regex for System Messages by **@danny-avila** in [#7245](https://github.com/danny-avila/LibreChat/pull/7245)
- 🔖 fix: Custom Headers for Initial MCP SSE Connection by **@danny-avila** in [#7246](https://github.com/danny-avila/LibreChat/pull/7246)
- 🛡️ fix: Deep Clone `MCPOptions` for User MCP Connections by **@danny-avila** in [#7247](https://github.com/danny-avila/LibreChat/pull/7247)
- 🔄 fix: URL Param Race Condition and File Draft Persistence by **@danny-avila** in [#7257](https://github.com/danny-avila/LibreChat/pull/7257)
- 🔄 fix: Assistants Endpoint & Minor Issues by **@danny-avila** in [#7274](https://github.com/danny-avila/LibreChat/pull/7274)
- 🔄 fix: Ollama Think Tag Edge Case with Tools by **@danny-avila** in [#7275](https://github.com/danny-avila/LibreChat/pull/7275)
- 🔧 fix: Google Gemma Support & OpenAI Reasoning Instructions by **@danny-avila** in [#7196](https://github.com/danny-avila/Chat/pull/7196)
- 🛠️ fix: Conversation Navigation State by **@danny-avila** in [#7210](https://github.com/danny-avila/Chat/pull/7210)
- 🔄 fix: o-Series Model Regex for System Messages by **@danny-avila** in [#7245](https://github.com/danny-avila/Chat/pull/7245)
- 🔖 fix: Custom Headers for Initial MCP SSE Connection by **@danny-avila** in [#7246](https://github.com/danny-avila/Chat/pull/7246)
- 🛡️ fix: Deep Clone `MCPOptions` for User MCP Connections by **@danny-avila** in [#7247](https://github.com/danny-avila/Chat/pull/7247)
- 🔄 fix: URL Param Race Condition and File Draft Persistence by **@danny-avila** in [#7257](https://github.com/danny-avila/Chat/pull/7257)
- 🔄 fix: Assistants Endpoint & Minor Issues by **@danny-avila** in [#7274](https://github.com/danny-avila/Chat/pull/7274)
- 🔄 fix: Ollama Think Tag Edge Case with Tools by **@danny-avila** in [#7275](https://github.com/danny-avila/Chat/pull/7275)
### ⚙️ Other Changes
- 📜 docs: CHANGELOG for release v0.7.8-rc1 by **@github-actions[bot]** in [#7153](https://github.com/danny-avila/LibreChat/pull/7153)
- 🔄 refactor: Artifact Visibility Management by **@danny-avila** in [#7181](https://github.com/danny-avila/LibreChat/pull/7181)
- 📦 chore: Bump Package Security by **@danny-avila** in [#7183](https://github.com/danny-avila/LibreChat/pull/7183)
- 🌿 refactor: Unmount Fork Popover on Hide for Better Performance by **@danny-avila** in [#7189](https://github.com/danny-avila/LibreChat/pull/7189)
- 🧰 chore: ESLint configuration to enforce Prettier formatting rules by **@mawburn** in [#7186](https://github.com/danny-avila/LibreChat/pull/7186)
- 🎨 style: Improve KaTeX Rendering for LaTeX Equations by **@andresgit** in [#7223](https://github.com/danny-avila/LibreChat/pull/7223)
- 📝 docs: Update `.env.example` Google models by **@marlonka** in [#7254](https://github.com/danny-avila/LibreChat/pull/7254)
- 💬 refactor: MCP Chat Visibility Option, Google Rates, Remove OpenAPI Plugins by **@danny-avila** in [#7286](https://github.com/danny-avila/LibreChat/pull/7286)
- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7214](https://github.com/danny-avila/LibreChat/pull/7214)
- 📜 docs: CHANGELOG for release v0.7.8-rc1 by **@github-actions[bot]** in [#7153](https://github.com/danny-avila/Chat/pull/7153)
- 🔄 refactor: Artifact Visibility Management by **@danny-avila** in [#7181](https://github.com/danny-avila/Chat/pull/7181)
- 📦 chore: Bump Package Security by **@danny-avila** in [#7183](https://github.com/danny-avila/Chat/pull/7183)
- 🌿 refactor: Unmount Fork Popover on Hide for Better Performance by **@danny-avila** in [#7189](https://github.com/danny-avila/Chat/pull/7189)
- 🧰 chore: ESLint configuration to enforce Prettier formatting rules by **@mawburn** in [#7186](https://github.com/danny-avila/Chat/pull/7186)
- 🎨 style: Improve KaTeX Rendering for LaTeX Equations by **@andresgit** in [#7223](https://github.com/danny-avila/Chat/pull/7223)
- 📝 docs: Update `.env.example` Google models by **@marlonka** in [#7254](https://github.com/danny-avila/Chat/pull/7254)
- 💬 refactor: MCP Chat Visibility Option, Google Rates, Remove OpenAPI Plugins by **@danny-avila** in [#7286](https://github.com/danny-avila/Chat/pull/7286)
- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7214](https://github.com/danny-avila/Chat/pull/7214)
[See full release details][release-v0.7.8]
[release-v0.7.8]: https://github.com/danny-avila/LibreChat/releases/tag/v0.7.8
[release-v0.7.8]: https://github.com/danny-avila/Chat/releases/tag/v0.7.8
---
## [v0.7.8-rc1] -
@@ -96,141 +96,141 @@ Changes from v0.7.7 to v0.7.8-rc1.
### ✨ New Features
- 🔍 feat: Mistral OCR API / Upload Files as Text by **@danny-avila** in [#6274](https://github.com/danny-avila/LibreChat/pull/6274)
- 🤖 feat: Support OpenAI Web Search models by **@danny-avila** in [#6313](https://github.com/danny-avila/LibreChat/pull/6313)
- 🔗 feat: Agent Chain (Mixture-of-Agents) by **@danny-avila** in [#6374](https://github.com/danny-avila/LibreChat/pull/6374)
- ⌛ feat: `initTimeout` for Slow Starting MCP Servers by **@perweij** in [#6383](https://github.com/danny-avila/LibreChat/pull/6383)
- 🚀 feat: `S3` Integration for File handling and Image uploads by **@rubentalstra** in [#6142](https://github.com/danny-avila/LibreChat/pull/6142)
- 🔒feat: Enable OpenID Auto-Redirect by **@leondape** in [#6066](https://github.com/danny-avila/LibreChat/pull/6066)
- 🚀 feat: Integrate `Azure Blob Storage` for file handling and image uploads by **@rubentalstra** in [#6153](https://github.com/danny-avila/LibreChat/pull/6153)
- 🚀 feat: Add support for custom `AWS` endpoint in `S3` by **@rubentalstra** in [#6431](https://github.com/danny-avila/LibreChat/pull/6431)
- 🚀 feat: Add support for LDAP STARTTLS in LDAP authentication by **@rubentalstra** in [#6438](https://github.com/danny-avila/LibreChat/pull/6438)
- 🚀 feat: Refactor schema exports and update package version to 0.0.4 by **@rubentalstra** in [#6455](https://github.com/danny-avila/LibreChat/pull/6455)
- 🔼 feat: Add Auto Submit For URL Query Params by **@mjaverto** in [#6440](https://github.com/danny-avila/LibreChat/pull/6440)
- 🛠 feat: Enhance Redis Integration, Rate Limiters & Log Headers by **@danny-avila** in [#6462](https://github.com/danny-avila/LibreChat/pull/6462)
- 💵 feat: Add Automatic Balance Refill by **@rubentalstra** in [#6452](https://github.com/danny-avila/LibreChat/pull/6452)
- 🗣️ feat: add support for gpt-4o-transcribe models by **@berry-13** in [#6483](https://github.com/danny-avila/LibreChat/pull/6483)
- 🎨 feat: UI Refresh for Enhanced UX by **@berry-13** in [#6346](https://github.com/danny-avila/LibreChat/pull/6346)
- 🌍 feat: Add support for Hungarian language localization by **@rubentalstra** in [#6508](https://github.com/danny-avila/LibreChat/pull/6508)
- 🚀 feat: Add Gemini 2.5 Token/Context Values, Increase Max Possible Output to 64k by **@danny-avila** in [#6563](https://github.com/danny-avila/LibreChat/pull/6563)
- 🚀 feat: Enhance MCP Connections For Multi-User Support by **@danny-avila** in [#6610](https://github.com/danny-avila/LibreChat/pull/6610)
- 🚀 feat: Enhance S3 URL Expiry with Refresh; fix: S3 File Deletion by **@danny-avila** in [#6647](https://github.com/danny-avila/LibreChat/pull/6647)
- 🚀 feat: enhance UI components and refactor settings by **@berry-13** in [#6625](https://github.com/danny-avila/LibreChat/pull/6625)
- 💬 feat: move TemporaryChat to the Header by **@berry-13** in [#6646](https://github.com/danny-avila/LibreChat/pull/6646)
- 🚀 feat: Use Model Specs + Specific Endpoints, Limit Providers for Agents by **@danny-avila** in [#6650](https://github.com/danny-avila/LibreChat/pull/6650)
- 🪙 feat: Sync Balance Config on Login by **@danny-avila** in [#6671](https://github.com/danny-avila/LibreChat/pull/6671)
- 🔦 feat: MCP Support for Non-Agent Endpoints by **@danny-avila** in [#6775](https://github.com/danny-avila/LibreChat/pull/6775)
- 🗃️ feat: Code Interpreter File Persistence between Sessions by **@danny-avila** in [#6790](https://github.com/danny-avila/LibreChat/pull/6790)
- 🖥️ feat: Code Interpreter API for Non-Agent Endpoints by **@danny-avila** in [#6803](https://github.com/danny-avila/LibreChat/pull/6803)
- ⚡ feat: Self-hosted Artifacts Static Bundler URL by **@danny-avila** in [#6827](https://github.com/danny-avila/LibreChat/pull/6827)
- 🐳 feat: Add Jemalloc and UV to Docker Builds by **@danny-avila** in [#6836](https://github.com/danny-avila/LibreChat/pull/6836)
- 🤖 feat: GPT-4.1 by **@danny-avila** in [#6880](https://github.com/danny-avila/LibreChat/pull/6880)
- 👋 feat: remove Edge TTS by **@berry-13** in [#6885](https://github.com/danny-avila/LibreChat/pull/6885)
- feat: nav optimization by **@berry-13** in [#5785](https://github.com/danny-avila/LibreChat/pull/5785)
- 🗺️ feat: Add Parameter Location Mapping for OpenAPI actions by **@peeeteeer** in [#6858](https://github.com/danny-avila/LibreChat/pull/6858)
- 🤖 feat: Support `o4-mini` and `o3` Models by **@danny-avila** in [#6928](https://github.com/danny-avila/LibreChat/pull/6928)
- 🎨 feat: OpenAI Image Tools (GPT-Image-1) by **@danny-avila** in [#7079](https://github.com/danny-avila/LibreChat/pull/7079)
- 🗓️ feat: Add Special Variables for Prompts & Agents, Prompt UI Improvements by **@danny-avila** in [#7123](https://github.com/danny-avila/LibreChat/pull/7123)
- 🔍 feat: Mistral OCR API / Upload Files as Text by **@danny-avila** in [#6274](https://github.com/danny-avila/Chat/pull/6274)
- 🤖 feat: Support OpenAI Web Search models by **@danny-avila** in [#6313](https://github.com/danny-avila/Chat/pull/6313)
- 🔗 feat: Agent Chain (Mixture-of-Agents) by **@danny-avila** in [#6374](https://github.com/danny-avila/Chat/pull/6374)
- ⌛ feat: `initTimeout` for Slow Starting MCP Servers by **@perweij** in [#6383](https://github.com/danny-avila/Chat/pull/6383)
- 🚀 feat: `S3` Integration for File handling and Image uploads by **@rubentalstra** in [#6142](https://github.com/danny-avila/Chat/pull/6142)
- 🔒feat: Enable OpenID Auto-Redirect by **@leondape** in [#6066](https://github.com/danny-avila/Chat/pull/6066)
- 🚀 feat: Integrate `Azure Blob Storage` for file handling and image uploads by **@rubentalstra** in [#6153](https://github.com/danny-avila/Chat/pull/6153)
- 🚀 feat: Add support for custom `AWS` endpoint in `S3` by **@rubentalstra** in [#6431](https://github.com/danny-avila/Chat/pull/6431)
- 🚀 feat: Add support for LDAP STARTTLS in LDAP authentication by **@rubentalstra** in [#6438](https://github.com/danny-avila/Chat/pull/6438)
- 🚀 feat: Refactor schema exports and update package version to 0.0.4 by **@rubentalstra** in [#6455](https://github.com/danny-avila/Chat/pull/6455)
- 🔼 feat: Add Auto Submit For URL Query Params by **@mjaverto** in [#6440](https://github.com/danny-avila/Chat/pull/6440)
- 🛠 feat: Enhance Redis Integration, Rate Limiters & Log Headers by **@danny-avila** in [#6462](https://github.com/danny-avila/Chat/pull/6462)
- 💵 feat: Add Automatic Balance Refill by **@rubentalstra** in [#6452](https://github.com/danny-avila/Chat/pull/6452)
- 🗣️ feat: add support for gpt-4o-transcribe models by **@berry-13** in [#6483](https://github.com/danny-avila/Chat/pull/6483)
- 🎨 feat: UI Refresh for Enhanced UX by **@berry-13** in [#6346](https://github.com/danny-avila/Chat/pull/6346)
- 🌍 feat: Add support for Hungarian language localization by **@rubentalstra** in [#6508](https://github.com/danny-avila/Chat/pull/6508)
- 🚀 feat: Add Gemini 2.5 Token/Context Values, Increase Max Possible Output to 64k by **@danny-avila** in [#6563](https://github.com/danny-avila/Chat/pull/6563)
- 🚀 feat: Enhance MCP Connections For Multi-User Support by **@danny-avila** in [#6610](https://github.com/danny-avila/Chat/pull/6610)
- 🚀 feat: Enhance S3 URL Expiry with Refresh; fix: S3 File Deletion by **@danny-avila** in [#6647](https://github.com/danny-avila/Chat/pull/6647)
- 🚀 feat: enhance UI components and refactor settings by **@berry-13** in [#6625](https://github.com/danny-avila/Chat/pull/6625)
- 💬 feat: move TemporaryChat to the Header by **@berry-13** in [#6646](https://github.com/danny-avila/Chat/pull/6646)
- 🚀 feat: Use Model Specs + Specific Endpoints, Limit Providers for Agents by **@danny-avila** in [#6650](https://github.com/danny-avila/Chat/pull/6650)
- 🪙 feat: Sync Balance Config on Login by **@danny-avila** in [#6671](https://github.com/danny-avila/Chat/pull/6671)
- 🔦 feat: MCP Support for Non-Agent Endpoints by **@danny-avila** in [#6775](https://github.com/danny-avila/Chat/pull/6775)
- 🗃️ feat: Code Interpreter File Persistence between Sessions by **@danny-avila** in [#6790](https://github.com/danny-avila/Chat/pull/6790)
- 🖥️ feat: Code Interpreter API for Non-Agent Endpoints by **@danny-avila** in [#6803](https://github.com/danny-avila/Chat/pull/6803)
- ⚡ feat: Self-hosted Artifacts Static Bundler URL by **@danny-avila** in [#6827](https://github.com/danny-avila/Chat/pull/6827)
- 🐳 feat: Add Jemalloc and UV to Docker Builds by **@danny-avila** in [#6836](https://github.com/danny-avila/Chat/pull/6836)
- 🤖 feat: GPT-4.1 by **@danny-avila** in [#6880](https://github.com/danny-avila/Chat/pull/6880)
- 👋 feat: remove Edge TTS by **@berry-13** in [#6885](https://github.com/danny-avila/Chat/pull/6885)
- feat: nav optimization by **@berry-13** in [#5785](https://github.com/danny-avila/Chat/pull/5785)
- 🗺️ feat: Add Parameter Location Mapping for OpenAPI actions by **@peeeteeer** in [#6858](https://github.com/danny-avila/Chat/pull/6858)
- 🤖 feat: Support `o4-mini` and `o3` Models by **@danny-avila** in [#6928](https://github.com/danny-avila/Chat/pull/6928)
- 🎨 feat: OpenAI Image Tools (GPT-Image-1) by **@danny-avila** in [#7079](https://github.com/danny-avila/Chat/pull/7079)
- 🗓️ feat: Add Special Variables for Prompts & Agents, Prompt UI Improvements by **@danny-avila** in [#7123](https://github.com/danny-avila/Chat/pull/7123)
### 🌍 Internationalization
- 🌍 i18n: Add Thai Language Support and Update Translations by **@rubentalstra** in [#6219](https://github.com/danny-avila/LibreChat/pull/6219)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6220](https://github.com/danny-avila/LibreChat/pull/6220)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6240](https://github.com/danny-avila/LibreChat/pull/6240)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6241](https://github.com/danny-avila/LibreChat/pull/6241)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6277](https://github.com/danny-avila/LibreChat/pull/6277)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6414](https://github.com/danny-avila/LibreChat/pull/6414)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6505](https://github.com/danny-avila/LibreChat/pull/6505)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6530](https://github.com/danny-avila/LibreChat/pull/6530)
- 🌍 i18n: Add Persian Localization Support by **@rubentalstra** in [#6669](https://github.com/danny-avila/LibreChat/pull/6669)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6667](https://github.com/danny-avila/LibreChat/pull/6667)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7126](https://github.com/danny-avila/LibreChat/pull/7126)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7148](https://github.com/danny-avila/LibreChat/pull/7148)
- 🌍 i18n: Add Thai Language Support and Update Translations by **@rubentalstra** in [#6219](https://github.com/danny-avila/Chat/pull/6219)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6220](https://github.com/danny-avila/Chat/pull/6220)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6240](https://github.com/danny-avila/Chat/pull/6240)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6241](https://github.com/danny-avila/Chat/pull/6241)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6277](https://github.com/danny-avila/Chat/pull/6277)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6414](https://github.com/danny-avila/Chat/pull/6414)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6505](https://github.com/danny-avila/Chat/pull/6505)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6530](https://github.com/danny-avila/Chat/pull/6530)
- 🌍 i18n: Add Persian Localization Support by **@rubentalstra** in [#6669](https://github.com/danny-avila/Chat/pull/6669)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6667](https://github.com/danny-avila/Chat/pull/6667)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7126](https://github.com/danny-avila/Chat/pull/7126)
- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7148](https://github.com/danny-avila/Chat/pull/7148)
### 👐 Accessibility
- 🎨 a11y: Update Model Spec Description Text by **@berry-13** in [#6294](https://github.com/danny-avila/LibreChat/pull/6294)
- 🗑️ a11y: Add Accessible Name to Button for File Attachment Removal by **@kangabell** in [#6709](https://github.com/danny-avila/LibreChat/pull/6709)
- ⌨️ a11y: enhance accessibility & visual consistency by **@berry-13** in [#6866](https://github.com/danny-avila/LibreChat/pull/6866)
- 🙌 a11y: Searchbar/Conversations List Focus by **@danny-avila** in [#7096](https://github.com/danny-avila/LibreChat/pull/7096)
- 👐 a11y: Improve Fork and SplitText Accessibility by **@danny-avila** in [#7147](https://github.com/danny-avila/LibreChat/pull/7147)
- 🎨 a11y: Update Model Spec Description Text by **@berry-13** in [#6294](https://github.com/danny-avila/Chat/pull/6294)
- 🗑️ a11y: Add Accessible Name to Button for File Attachment Removal by **@kangabell** in [#6709](https://github.com/danny-avila/Chat/pull/6709)
- ⌨️ a11y: enhance accessibility & visual consistency by **@berry-13** in [#6866](https://github.com/danny-avila/Chat/pull/6866)
- 🙌 a11y: Searchbar/Conversations List Focus by **@danny-avila** in [#7096](https://github.com/danny-avila/Chat/pull/7096)
- 👐 a11y: Improve Fork and SplitText Accessibility by **@danny-avila** in [#7147](https://github.com/danny-avila/Chat/pull/7147)
### 🔧 Fixes
- 🐛 fix: Avatar Type Definitions in Agent/Assistant Schemas by **@danny-avila** in [#6235](https://github.com/danny-avila/LibreChat/pull/6235)
- 🔧 fix: MeiliSearch Field Error and Patch Incorrect Import by #6210 by **@rubentalstra** in [#6245](https://github.com/danny-avila/LibreChat/pull/6245)
- 🔏 fix: Enhance Two-Factor Authentication by **@rubentalstra** in [#6247](https://github.com/danny-avila/LibreChat/pull/6247)
- 🐛 fix: Await saveMessage in abortMiddleware to ensure proper execution by **@sh4shii** in [#6248](https://github.com/danny-avila/LibreChat/pull/6248)
- 🔧 fix: Axios Proxy Usage And Bump `mongoose` by **@danny-avila** in [#6298](https://github.com/danny-avila/LibreChat/pull/6298)
- 🔧 fix: comment out MCP servers to resolve service run issues by **@KunalScriptz** in [#6316](https://github.com/danny-avila/LibreChat/pull/6316)
- 🔧 fix: Update Token Calculations and Mapping, MCP `env` Initialization by **@danny-avila** in [#6406](https://github.com/danny-avila/LibreChat/pull/6406)
- 🐞 fix: Agent "Resend" Message Attachments + Source Icon Styling by **@danny-avila** in [#6408](https://github.com/danny-avila/LibreChat/pull/6408)
- 🐛 fix: Prevent Crash on Duplicate Message ID by **@Odrec** in [#6392](https://github.com/danny-avila/LibreChat/pull/6392)
- 🔐 fix: Invalid Key Length in 2FA Encryption by **@rubentalstra** in [#6432](https://github.com/danny-avila/LibreChat/pull/6432)
- 🏗️ fix: Fix Agents Token Spend Race Conditions, Expand Test Coverage by **@danny-avila** in [#6480](https://github.com/danny-avila/LibreChat/pull/6480)
- 🔃 fix: Draft Clearing, Claude Titles, Remove Default Vision Max Tokens by **@danny-avila** in [#6501](https://github.com/danny-avila/LibreChat/pull/6501)
- 🔧 fix: Update username reference to use user.name in greeting display by **@rubentalstra** in [#6534](https://github.com/danny-avila/LibreChat/pull/6534)
- 🔧 fix: S3 Download Stream with Key Extraction and Blob Storage Encoding for Vision by **@danny-avila** in [#6557](https://github.com/danny-avila/LibreChat/pull/6557)
- 🔧 fix: Mistral type strictness for `usage` & update token values/windows by **@danny-avila** in [#6562](https://github.com/danny-avila/LibreChat/pull/6562)
- 🔧 fix: Consolidate Text Parsing and TTS Edge Initialization by **@danny-avila** in [#6582](https://github.com/danny-avila/LibreChat/pull/6582)
- 🔧 fix: Ensure continuation in image processing on base64 encoding from Blob Storage by **@danny-avila** in [#6619](https://github.com/danny-avila/LibreChat/pull/6619)
- ✉️ fix: Fallback For User Name In Email Templates by **@danny-avila** in [#6620](https://github.com/danny-avila/LibreChat/pull/6620)
- 🔧 fix: Azure Blob Integration and File Source References by **@rubentalstra** in [#6575](https://github.com/danny-avila/LibreChat/pull/6575)
- 🐛 fix: Safeguard against undefined addedEndpoints by **@wipash** in [#6654](https://github.com/danny-avila/LibreChat/pull/6654)
- 🤖 fix: Gemini 2.5 Vision Support by **@danny-avila** in [#6663](https://github.com/danny-avila/LibreChat/pull/6663)
- 🔄 fix: Avatar & Error Handling Enhancements by **@danny-avila** in [#6687](https://github.com/danny-avila/LibreChat/pull/6687)
- 🔧 fix: Chat Middleware, Zod Conversion, Auto-Save and S3 URL Refresh by **@danny-avila** in [#6720](https://github.com/danny-avila/LibreChat/pull/6720)
- 🔧 fix: Agent Capability Checks & DocumentDB Compatibility for Agent Resource Removal by **@danny-avila** in [#6726](https://github.com/danny-avila/LibreChat/pull/6726)
- 🔄 fix: Improve audio MIME type detection and handling by **@berry-13** in [#6707](https://github.com/danny-avila/LibreChat/pull/6707)
- 🪺 fix: Update Role Handling due to New Schema Shape by **@danny-avila** in [#6774](https://github.com/danny-avila/LibreChat/pull/6774)
- 🗨️ fix: Show ModelSpec Greeting by **@berry-13** in [#6770](https://github.com/danny-avila/LibreChat/pull/6770)
- 🔧 fix: Keyv and Proxy Issues, and More Memory Optimizations by **@danny-avila** in [#6867](https://github.com/danny-avila/LibreChat/pull/6867)
- ✨ fix: Implement dynamic text sizing for greeting and name display by **@berry-13** in [#6833](https://github.com/danny-avila/LibreChat/pull/6833)
- 📝 fix: Mistral OCR Image Support and Azure Agent Titles by **@danny-avila** in [#6901](https://github.com/danny-avila/LibreChat/pull/6901)
- 📢 fix: Invalid `engineTTS` and Conversation State on Navigation by **@berry-13** in [#6904](https://github.com/danny-avila/LibreChat/pull/6904)
- 🛠️ fix: Improve Accessibility and Display of Conversation Menu by **@danny-avila** in [#6913](https://github.com/danny-avila/LibreChat/pull/6913)
- 🔧 fix: Agent Resource Form, Convo Menu Style, Ensure Draft Clears on Submission by **@danny-avila** in [#6925](https://github.com/danny-avila/LibreChat/pull/6925)
- 🔀 fix: MCP Improvements, Auto-Save Drafts, Artifact Markup by **@danny-avila** in [#7040](https://github.com/danny-avila/LibreChat/pull/7040)
- 🐋 fix: Improve Deepseek Compatbility by **@danny-avila** in [#7132](https://github.com/danny-avila/LibreChat/pull/7132)
- 🐙 fix: Add Redis Ping Interval to Prevent Connection Drops by **@peeeteeer** in [#7127](https://github.com/danny-avila/LibreChat/pull/7127)
- 🐛 fix: Avatar Type Definitions in Agent/Assistant Schemas by **@danny-avila** in [#6235](https://github.com/danny-avila/Chat/pull/6235)
- 🔧 fix: MeiliSearch Field Error and Patch Incorrect Import by #6210 by **@rubentalstra** in [#6245](https://github.com/danny-avila/Chat/pull/6245)
- 🔏 fix: Enhance Two-Factor Authentication by **@rubentalstra** in [#6247](https://github.com/danny-avila/Chat/pull/6247)
- 🐛 fix: Await saveMessage in abortMiddleware to ensure proper execution by **@sh4shii** in [#6248](https://github.com/danny-avila/Chat/pull/6248)
- 🔧 fix: Axios Proxy Usage And Bump `mongoose` by **@danny-avila** in [#6298](https://github.com/danny-avila/Chat/pull/6298)
- 🔧 fix: comment out MCP servers to resolve service run issues by **@KunalScriptz** in [#6316](https://github.com/danny-avila/Chat/pull/6316)
- 🔧 fix: Update Token Calculations and Mapping, MCP `env` Initialization by **@danny-avila** in [#6406](https://github.com/danny-avila/Chat/pull/6406)
- 🐞 fix: Agent "Resend" Message Attachments + Source Icon Styling by **@danny-avila** in [#6408](https://github.com/danny-avila/Chat/pull/6408)
- 🐛 fix: Prevent Crash on Duplicate Message ID by **@Odrec** in [#6392](https://github.com/danny-avila/Chat/pull/6392)
- 🔐 fix: Invalid Key Length in 2FA Encryption by **@rubentalstra** in [#6432](https://github.com/danny-avila/Chat/pull/6432)
- 🏗️ fix: Fix Agents Token Spend Race Conditions, Expand Test Coverage by **@danny-avila** in [#6480](https://github.com/danny-avila/Chat/pull/6480)
- 🔃 fix: Draft Clearing, Claude Titles, Remove Default Vision Max Tokens by **@danny-avila** in [#6501](https://github.com/danny-avila/Chat/pull/6501)
- 🔧 fix: Update username reference to use user.name in greeting display by **@rubentalstra** in [#6534](https://github.com/danny-avila/Chat/pull/6534)
- 🔧 fix: S3 Download Stream with Key Extraction and Blob Storage Encoding for Vision by **@danny-avila** in [#6557](https://github.com/danny-avila/Chat/pull/6557)
- 🔧 fix: Mistral type strictness for `usage` & update token values/windows by **@danny-avila** in [#6562](https://github.com/danny-avila/Chat/pull/6562)
- 🔧 fix: Consolidate Text Parsing and TTS Edge Initialization by **@danny-avila** in [#6582](https://github.com/danny-avila/Chat/pull/6582)
- 🔧 fix: Ensure continuation in image processing on base64 encoding from Blob Storage by **@danny-avila** in [#6619](https://github.com/danny-avila/Chat/pull/6619)
- ✉️ fix: Fallback For User Name In Email Templates by **@danny-avila** in [#6620](https://github.com/danny-avila/Chat/pull/6620)
- 🔧 fix: Azure Blob Integration and File Source References by **@rubentalstra** in [#6575](https://github.com/danny-avila/Chat/pull/6575)
- 🐛 fix: Safeguard against undefined addedEndpoints by **@wipash** in [#6654](https://github.com/danny-avila/Chat/pull/6654)
- 🤖 fix: Gemini 2.5 Vision Support by **@danny-avila** in [#6663](https://github.com/danny-avila/Chat/pull/6663)
- 🔄 fix: Avatar & Error Handling Enhancements by **@danny-avila** in [#6687](https://github.com/danny-avila/Chat/pull/6687)
- 🔧 fix: Chat Middleware, Zod Conversion, Auto-Save and S3 URL Refresh by **@danny-avila** in [#6720](https://github.com/danny-avila/Chat/pull/6720)
- 🔧 fix: Agent Capability Checks & DocumentDB Compatibility for Agent Resource Removal by **@danny-avila** in [#6726](https://github.com/danny-avila/Chat/pull/6726)
- 🔄 fix: Improve audio MIME type detection and handling by **@berry-13** in [#6707](https://github.com/danny-avila/Chat/pull/6707)
- 🪺 fix: Update Role Handling due to New Schema Shape by **@danny-avila** in [#6774](https://github.com/danny-avila/Chat/pull/6774)
- 🗨️ fix: Show ModelSpec Greeting by **@berry-13** in [#6770](https://github.com/danny-avila/Chat/pull/6770)
- 🔧 fix: Keyv and Proxy Issues, and More Memory Optimizations by **@danny-avila** in [#6867](https://github.com/danny-avila/Chat/pull/6867)
- ✨ fix: Implement dynamic text sizing for greeting and name display by **@berry-13** in [#6833](https://github.com/danny-avila/Chat/pull/6833)
- 📝 fix: Mistral OCR Image Support and Azure Agent Titles by **@danny-avila** in [#6901](https://github.com/danny-avila/Chat/pull/6901)
- 📢 fix: Invalid `engineTTS` and Conversation State on Navigation by **@berry-13** in [#6904](https://github.com/danny-avila/Chat/pull/6904)
- 🛠️ fix: Improve Accessibility and Display of Conversation Menu by **@danny-avila** in [#6913](https://github.com/danny-avila/Chat/pull/6913)
- 🔧 fix: Agent Resource Form, Convo Menu Style, Ensure Draft Clears on Submission by **@danny-avila** in [#6925](https://github.com/danny-avila/Chat/pull/6925)
- 🔀 fix: MCP Improvements, Auto-Save Drafts, Artifact Markup by **@danny-avila** in [#7040](https://github.com/danny-avila/Chat/pull/7040)
- 🐋 fix: Improve Deepseek Compatbility by **@danny-avila** in [#7132](https://github.com/danny-avila/Chat/pull/7132)
- 🐙 fix: Add Redis Ping Interval to Prevent Connection Drops by **@peeeteeer** in [#7127](https://github.com/danny-avila/Chat/pull/7127)
### ⚙️ Other Changes
- 📦 refactor: Move DB Models to `@librechat/data-schemas` by **@rubentalstra** in [#6210](https://github.com/danny-avila/LibreChat/pull/6210)
- 📦 chore: Patch `axios` to address CVE-2025-27152 by **@danny-avila** in [#6222](https://github.com/danny-avila/LibreChat/pull/6222)
- ⚠️ refactor: Use Error Content Part Instead Of Throwing Error for Agents by **@danny-avila** in [#6262](https://github.com/danny-avila/LibreChat/pull/6262)
- 🏃‍♂️ refactor: Improve Agent Run Context & Misc. Changes by **@danny-avila** in [#6448](https://github.com/danny-avila/LibreChat/pull/6448)
- 📝 docs: librechat.example.yaml by **@ineiti** in [#6442](https://github.com/danny-avila/LibreChat/pull/6442)
- 🏃‍♂️ refactor: More Agent Context Improvements during Run by **@danny-avila** in [#6477](https://github.com/danny-avila/LibreChat/pull/6477)
- 🔃 refactor: Allow streaming for `o1` models by **@danny-avila** in [#6509](https://github.com/danny-avila/LibreChat/pull/6509)
- 🔧 chore: `Vite` Plugin Upgrades & Config Optimizations by **@rubentalstra** in [#6547](https://github.com/danny-avila/LibreChat/pull/6547)
- 🔧 refactor: Consolidate Logging, Model Selection & Actions Optimizations, Minor Fixes by **@danny-avila** in [#6553](https://github.com/danny-avila/LibreChat/pull/6553)
- 🎨 style: Address Minor UI Refresh Issues by **@berry-13** in [#6552](https://github.com/danny-avila/LibreChat/pull/6552)
- 🔧 refactor: Enhance Model & Endpoint Configurations with Global Indicators 🌍 by **@berry-13** in [#6578](https://github.com/danny-avila/LibreChat/pull/6578)
- 💬 style: Chat UI, Greeting, and Message adjustments by **@berry-13** in [#6612](https://github.com/danny-avila/LibreChat/pull/6612)
- ⚡ refactor: DocumentDB Compatibility for Balance Updates by **@danny-avila** in [#6673](https://github.com/danny-avila/LibreChat/pull/6673)
- 🧹 chore: Update ESLint rules for React hooks by **@rubentalstra** in [#6685](https://github.com/danny-avila/LibreChat/pull/6685)
- 🪙 chore: Update Gemini Pricing by **@RedwindA** in [#6731](https://github.com/danny-avila/LibreChat/pull/6731)
- 🪺 refactor: Nest Permission fields for Roles by **@rubentalstra** in [#6487](https://github.com/danny-avila/LibreChat/pull/6487)
- 📦 chore: Update `caniuse-lite` dependency to version 1.0.30001706 by **@rubentalstra** in [#6482](https://github.com/danny-avila/LibreChat/pull/6482)
- ⚙️ refactor: OAuth Flow Signal, Type Safety, Tool Progress & Updated Packages by **@danny-avila** in [#6752](https://github.com/danny-avila/LibreChat/pull/6752)
- 📦 chore: bump vite from 6.2.3 to 6.2.5 by **@dependabot[bot]** in [#6745](https://github.com/danny-avila/LibreChat/pull/6745)
- 💾 chore: Enhance Local Storage Handling and Update MCP SDK by **@danny-avila** in [#6809](https://github.com/danny-avila/LibreChat/pull/6809)
- 🤖 refactor: Improve Agents Memory Usage, Bump Keyv, Grok 3 by **@danny-avila** in [#6850](https://github.com/danny-avila/LibreChat/pull/6850)
- 💾 refactor: Enhance Memory In Image Encodings & Client Disposal by **@danny-avila** in [#6852](https://github.com/danny-avila/LibreChat/pull/6852)
- 🔁 refactor: Token Event Handler and Standardize `maxTokens` Key by **@danny-avila** in [#6886](https://github.com/danny-avila/LibreChat/pull/6886)
- 🔍 refactor: Search & Message Retrieval by **@berry-13** in [#6903](https://github.com/danny-avila/LibreChat/pull/6903)
- 🎨 style: standardize dropdown styling & fix z-Index layering by **@berry-13** in [#6939](https://github.com/danny-avila/LibreChat/pull/6939)
- 📙 docs: CONTRIBUTING.md by **@dblock** in [#6831](https://github.com/danny-avila/LibreChat/pull/6831)
- 🧭 refactor: Modernize Nav/Header by **@danny-avila** in [#7094](https://github.com/danny-avila/LibreChat/pull/7094)
- 🪶 refactor: Chat Input Focus for Conversation Navigations & ChatForm Optimizations by **@danny-avila** in [#7100](https://github.com/danny-avila/LibreChat/pull/7100)
- 🔃 refactor: Streamline Navigation, Message Loading UX by **@danny-avila** in [#7118](https://github.com/danny-avila/LibreChat/pull/7118)
- 📜 docs: Unreleased changelog by **@github-actions[bot]** in [#6265](https://github.com/danny-avila/LibreChat/pull/6265)
- 📦 refactor: Move DB Models to `@hanzochat/data-schemas` by **@rubentalstra** in [#6210](https://github.com/danny-avila/Chat/pull/6210)
- 📦 chore: Patch `axios` to address CVE-2025-27152 by **@danny-avila** in [#6222](https://github.com/danny-avila/Chat/pull/6222)
- ⚠️ refactor: Use Error Content Part Instead Of Throwing Error for Agents by **@danny-avila** in [#6262](https://github.com/danny-avila/Chat/pull/6262)
- 🏃‍♂️ refactor: Improve Agent Run Context & Misc. Changes by **@danny-avila** in [#6448](https://github.com/danny-avila/Chat/pull/6448)
- 📝 docs: chat.example.yaml by **@ineiti** in [#6442](https://github.com/danny-avila/Chat/pull/6442)
- 🏃‍♂️ refactor: More Agent Context Improvements during Run by **@danny-avila** in [#6477](https://github.com/danny-avila/Chat/pull/6477)
- 🔃 refactor: Allow streaming for `o1` models by **@danny-avila** in [#6509](https://github.com/danny-avila/Chat/pull/6509)
- 🔧 chore: `Vite` Plugin Upgrades & Config Optimizations by **@rubentalstra** in [#6547](https://github.com/danny-avila/Chat/pull/6547)
- 🔧 refactor: Consolidate Logging, Model Selection & Actions Optimizations, Minor Fixes by **@danny-avila** in [#6553](https://github.com/danny-avila/Chat/pull/6553)
- 🎨 style: Address Minor UI Refresh Issues by **@berry-13** in [#6552](https://github.com/danny-avila/Chat/pull/6552)
- 🔧 refactor: Enhance Model & Endpoint Configurations with Global Indicators 🌍 by **@berry-13** in [#6578](https://github.com/danny-avila/Chat/pull/6578)
- 💬 style: Chat UI, Greeting, and Message adjustments by **@berry-13** in [#6612](https://github.com/danny-avila/Chat/pull/6612)
- ⚡ refactor: DocumentDB Compatibility for Balance Updates by **@danny-avila** in [#6673](https://github.com/danny-avila/Chat/pull/6673)
- 🧹 chore: Update ESLint rules for React hooks by **@rubentalstra** in [#6685](https://github.com/danny-avila/Chat/pull/6685)
- 🪙 chore: Update Gemini Pricing by **@RedwindA** in [#6731](https://github.com/danny-avila/Chat/pull/6731)
- 🪺 refactor: Nest Permission fields for Roles by **@rubentalstra** in [#6487](https://github.com/danny-avila/Chat/pull/6487)
- 📦 chore: Update `caniuse-lite` dependency to version 1.0.30001706 by **@rubentalstra** in [#6482](https://github.com/danny-avila/Chat/pull/6482)
- ⚙️ refactor: OAuth Flow Signal, Type Safety, Tool Progress & Updated Packages by **@danny-avila** in [#6752](https://github.com/danny-avila/Chat/pull/6752)
- 📦 chore: bump vite from 6.2.3 to 6.2.5 by **@dependabot[bot]** in [#6745](https://github.com/danny-avila/Chat/pull/6745)
- 💾 chore: Enhance Local Storage Handling and Update MCP SDK by **@danny-avila** in [#6809](https://github.com/danny-avila/Chat/pull/6809)
- 🤖 refactor: Improve Agents Memory Usage, Bump Keyv, Grok 3 by **@danny-avila** in [#6850](https://github.com/danny-avila/Chat/pull/6850)
- 💾 refactor: Enhance Memory In Image Encodings & Client Disposal by **@danny-avila** in [#6852](https://github.com/danny-avila/Chat/pull/6852)
- 🔁 refactor: Token Event Handler and Standardize `maxTokens` Key by **@danny-avila** in [#6886](https://github.com/danny-avila/Chat/pull/6886)
- 🔍 refactor: Search & Message Retrieval by **@berry-13** in [#6903](https://github.com/danny-avila/Chat/pull/6903)
- 🎨 style: standardize dropdown styling & fix z-Index layering by **@berry-13** in [#6939](https://github.com/danny-avila/Chat/pull/6939)
- 📙 docs: CONTRIBUTING.md by **@dblock** in [#6831](https://github.com/danny-avila/Chat/pull/6831)
- 🧭 refactor: Modernize Nav/Header by **@danny-avila** in [#7094](https://github.com/danny-avila/Chat/pull/7094)
- 🪶 refactor: Chat Input Focus for Conversation Navigations & ChatForm Optimizations by **@danny-avila** in [#7100](https://github.com/danny-avila/Chat/pull/7100)
- 🔃 refactor: Streamline Navigation, Message Loading UX by **@danny-avila** in [#7118](https://github.com/danny-avila/Chat/pull/7118)
- 📜 docs: Unreleased changelog by **@github-actions[bot]** in [#6265](https://github.com/danny-avila/Chat/pull/6265)
[See full release details][release-v0.7.8-rc1]
[release-v0.7.8-rc1]: https://github.com/danny-avila/LibreChat/releases/tag/v0.7.8-rc1
[release-v0.7.8-rc1]: https://github.com/danny-avila/Chat/releases/tag/v0.7.8-rc1
---
+23 -23
View File
@@ -4,7 +4,7 @@ AI chat interface with multi-model support,
MCP integration, agents, and RAG. Live at **hanzo.chat**.
**Repo**: `github.com/hanzoai/chat`
**Upstream**: LibreChat (MIT) — internal package names kept (`@librechat/*`)
**Upstream**: Chat (MIT) — internal package names kept (`@hanzochat/*`)
**Package**: `@hanzochat/chat`
**Runtime**: Node.js 20 (Alpine)
@@ -52,7 +52,7 @@ client/ # React frontend (Vite)
src/routes/ # Client-side routing
src/store/ # State management
packages/
data-provider/ # Shared data layer (librechat-data-provider)
data-provider/ # Shared data layer (@hanzochat/data-provider)
data-schemas/ # Validation schemas
api/ # API client package (@hanzochat/api)
client/ # Shared client components
@@ -62,7 +62,7 @@ packages/
## Configuration
- `librechat.yaml` (or ConfigMap `chat-config` -> `/app/librechat.yaml`)
- `chat.yaml` (or ConfigMap `chat-config` -> `/app/chat.yaml`)
- `hanzo-chat.example.yaml` - Hanzo-specific example config
- `.env` for secrets
@@ -142,7 +142,7 @@ Security model (fail-closed, server-enforced):
## Cloud Agents (canonical /v1/agents)
Chat can RUN a user's canonical Hanzo Cloud agents (cloud `/v1/agents`, the ONE
production agent registry) from the thread — alongside the LibreChat-legacy local
production agent registry) from the thread — alongside the Chat-legacy local
agent builder, which is untouched.
- Two surfaces, ONE run path: the `/agent <name> [prompt]` slash command and the
@@ -197,7 +197,7 @@ agent builder, which is untouched.
`client/src/components/Chat/Input/AgentsCommand.tsx`, and the @mention wiring in
`client/src/hooks/Input/useMentions.ts` + `Mention.tsx`.
- Env: `HANZO_CLOUD_URL` (optional; falls back to the `OPENAI_BASE_URL` host).
- Convergence path (later): chat's LibreChat-legacy `/v1/chat/agents` CRUD should
- Convergence path (later): chat's Chat-legacy `/v1/chat/agents` CRUD should
converge onto cloud `/v1/agents`; this step only ADDS cloud-agent RUN.
## Unified cloud architecture (2026-07) — investigate-before-ripping map
@@ -216,7 +216,7 @@ Verified by full call-graph + route-table trace; do NOT rip blind.
config → LangChain OpenAI client → **`POST https://api.hanzo.ai/v1/chat/completions`**
(SSE stream, resumable via `GenerationJobManager`). Per-user `hk-` key +
per-org Commerce debit; fail-closed 402. THIS is the one inference path.
- **Code interpreter** → `LIBRECHAT_CODE_BASEURL` = cloud `/v1/exec`.
- **Code interpreter** → `CHAT_CODE_BASEURL` = cloud `/v1/exec`.
- **Web search** → `webSearch` block (searxng+firecrawl contracts) = cloud
`/v1/websearch`.
- **Cloud agents** → `POST /v1/chat/agents/cloud/:name/run` server-proxies to cloud
@@ -224,7 +224,7 @@ Verified by full call-graph + route-table trace; do NOT rip blind.
- **Model list**: curated **zen-only** (`fetch:false`) in the loaded config —
NO raw upstream names (brand policy). Authoritative prod list lives in the
`chat-config` ConfigMap (`universe infra/k8s/chat/configmap.yaml`); repo
`librechat.yaml` mirrors it (one way).
`chat.yaml` mirrors it (one way).
### DEAD residue — do NOT treat as a live backend
@@ -237,7 +237,7 @@ Verified by full call-graph + route-table trace; do NOT rip blind.
### The ONE real parallel store (FLAG — needs a Go-backend home)
LibreChat's Express backend owns, in **MongoDB** (`HanzoChat` DB), all of:
Chat's Express backend owns, in **MongoDB** (`HanzoChat` DB), all of:
`convos`, `messages`, `presets`, `prompts`/`promptGroups`, `users`, `balances`/
`transactions`, `files`, `sessions` (refresh-token hashes), plus agents/assistants/
memory/RBAC. Schemas: `packages/data-schemas/src/schema/*`. This is the shadow
@@ -246,9 +246,9 @@ store that is NOT on the Go backend.
- The Go backend (`hanzoai/ai`, mounted at bare `/v1/*` in cloud) DOES have a
persistence home, but under **casibase names** (`/v1/get-chats`, `/v1/get-chat`,
`/v1/add-chat`, `/v1/get-messages`, `/v1/add-message`, `/v1/get-usages`) — a
different schema/shape than LibreChat's Mongo.
different schema/shape than Chat's Mongo.
- The canonical OpenAPI repo has `chat/openapi.yaml` describing the INTENDED
LibreChat-shaped REST surface (`/v1/chat/convos`, `/v1/chat/messages`,
Chat-shaped REST surface (`/v1/chat/convos`, `/v1/chat/messages`,
`/v1/chat/presets`, `/v1/chat/balance`, `/v1/chat/auth/*`) — but the Go binary
**does not implement it yet**, and `ai/openapi.yaml` under-documents the real
casibase routes.
@@ -260,7 +260,7 @@ store that is NOT on the Go backend.
### IAM-native auth (HIP-0111) — federated to hanzo.id, LIVE
- **Prod (backend-proxied)**: LibreChat passport `openid-client` strategy,
- **Prod (backend-proxied)**: Chat passport `openid-client` strategy,
OIDC **discovery** from `${OPENID_ISSUER}` = `https://hanzo.id`
(`/.well-known/openid-configuration`; discovery fetched via in-cluster
`iam.hanzo.svc` to dodge the CF hairpin), client_id **`hanzo-chat`**, callback
@@ -284,7 +284,7 @@ store that is NOT on the Go backend.
`HanzoHeader` for cross-app chrome. Monochrome rebrand already done (grey ramp,
H mark, favicon = hanzo.app set).
- **`@hanzo/gui`** = a **Tamagui** fork (Next.js 15 / React 19, RN-web) — console's
stack. Forcing it into the Vite/React18 LibreChat client = a ground-up rewrite
stack. Forcing it into the Vite/React18 Chat client = a ground-up rewrite
of a live product; NOT done. Unify by widening `@hanzo/ui` adoption + matching
console's monochrome tokens, NOT by swapping component frameworks.
@@ -292,24 +292,24 @@ store that is NOT on the Go backend.
`loadCustomConfig.js` defaults to **`chat.yaml`** (`CONFIG_PATH || <root>/chat.yaml`).
Prod sets `CONFIG_PATH=/app/chat.yaml` (ConfigMap mount). Repo ships
`librechat.yaml` (reference); a deploy that doesn't set `CONFIG_PATH` to it (or
`chat.yaml` (reference); a deploy that doesn't set `CONFIG_PATH` to it (or
provide `chat.yaml`) falls back to the built-in `openAI` endpoint. `OPENAI_BASE_URL`
in `compose.prod.yml` is inert here (built-in openAI reads `OPENAI_REVERSE_PROXY`).
## Internal Package Names
These are kept as-is from upstream (npm deps, not worth renaming):
- `@hanzochat/api`, `@librechat/client`, `@librechat/data-schemas`, `librechat-data-provider`, `@librechat/agents`
- Functions: `extractLibreChatParams`, `importLibreChatConvo`
- Type names: `LibreChatKeys`, `LibreChatParams`
- Config filename: `librechat.yaml` (upstream convention)
- Env var: `LIBRECHAT_LOG_DIR`
- `@hanzochat/api`, `@hanzochat/client`, `@hanzochat/data-schemas`, `@hanzochat/data-provider`, `@hanzochat/agents`
- Functions: `extractChatParams`, `importChatConvo`
- Type names: `ChatKeys`, `ChatParams`
- Config filename: `chat.yaml` (upstream convention)
- Env var: `CHAT_LOG_DIR`
## Branding Cleanup Log
All user-visible `LibreChat` / `librechat.ai` references replaced with Hanzo equivalents:
- All `librechat.ai` URLs -> `hanzo.ai/docs/chat/...`
- `code.librechat.ai` -> `hanzo.ai/docs/chat/code-interpreter/...`
All user-visible `Chat` / `chat.ai` references replaced with Hanzo equivalents:
- All `chat.ai` URLs -> `hanzo.ai/docs/chat/...`
- `code.chat.ai` -> `hanzo.ai/docs/chat/code-interpreter/...`
- package.json repo URLs -> `github.com/hanzoai/chat`
- package.json homepages -> `hanzo.ai/chat`
- package.json descriptions -> "Hanzo Chat"
@@ -317,6 +317,6 @@ All user-visible `LibreChat` / `librechat.ai` references replaced with Hanzo equ
- Docker Compose MongoDB DB name -> `HanzoChat`
- GitHub workflow repo refs -> `hanzoai/chat`
- MCP User-Agent -> `HanzoChat-MCP-Client`
- JSDoc comments: LibreChat -> Hanzo Chat
- Log messages: LibreChat -> Hanzo Chat
- JSDoc comments: Chat -> Hanzo Chat
- Log messages: Chat -> Hanzo Chat
- Helm chart URLs -> hanzo.ai/docs/chat/...
+1 -1
View File
@@ -134,7 +134,7 @@ build-static-local:
@echo "$(GREEN)Building static SPA locally...$(NC)"
@cp .env.static .env
@pnpm run build:data-provider
@pnpm run --filter @librechat/client build
@pnpm run --filter @hanzochat/client build
@cd client && pnpm run build
@cp .env.backup .env 2>/dev/null || true
@echo "$(GREEN)Local build complete: client/dist/$(NC)"
+2 -2
View File
@@ -1,6 +1,6 @@
chat
Copyright (c) 2023 Hanzo AI Inc.
This product includes software from LibreChat (https://github.com/danny-avila/LibreChat), licensed under MIT:
This product includes software from Chat (https://github.com/danny-avila/Chat), licensed under MIT:
Copyright (c) 2023 LibreChat (Danny Avila)
Copyright (c) 2023 Chat (Danny Avila)
+54 -137
View File
@@ -1,168 +1,85 @@
<p align="center"><img src=".github/hero.svg" alt="chat" width="880"></p>
<p align="center"><img src=".github/hero.svg" alt="Hanzo Chat" width="880"></p>
# Hanzo AI Chat
# Hanzo Chat
AI-powered chat platform with enterprise features, using Hanzo's cloud API or local deployment.
The chat surface of the Hanzo AI cloud: multi-model chat with agents, tools, and retrieval, running on Hanzo's backend. Live at [hanzo.chat](https://hanzo.chat).
## Quick Start
Hanzo Chat is a sibling to [hanzo.app](https://hanzo.app) (the app builder) and the Hanzo console (admin). All inference, code execution, and web search route through the unified Hanzo API at `api.hanzo.ai/v1`, and sign-in is federated to Hanzo IAM ([hanzo.id](https://hanzo.id)).
## Features
- **Multi-model chat** — the Zen model family and other frontier models, served through `api.hanzo.ai`.
- **Agents** — build agents in the thread, or run your Hanzo Cloud agents (`/v1/agents`) with an `/agent` command or `@mention`.
- **MCP tools** — connect Model Context Protocol servers for tool use.
- **RAG** — chat over your own files and documents.
- **Web search** — grounded answers via Hanzo web search.
- **Code interpreter** — run code in a sandboxed runtime.
- **Image generation** — generate images inline.
- **Guest chat** — try a free Zen model with no account (optional, off by default).
## Requirements
- Node.js 24 (see `.nvmrc`)
- pnpm 10
- A Hanzo API key — get one at [hanzo.ai/dashboard](https://hanzo.ai/dashboard)
## Quick start (Docker)
```bash
# Clone and setup
git clone https://github.com/hanzoai/chat.git
cd chat
# Copy environment template
cp .env.example .env
# Edit .env and add your Hanzo API key
# Get your key at: https://hanzo.ai/dashboard
nano .env
# Start the platform
cp .env.example .env # set HANZO_API_KEY
make up
```
Access the chat at http://localhost:3081
Open http://localhost:3080. `make up` starts the full stack (app, MongoDB, Meilisearch) from `compose.yml`; `make down` stops it.
## Development
### Basic Development (with hot reload)
```bash
make dev
pnpm install # install workspace dependencies
pnpm build:packages # build the shared workspace packages
pnpm backend:dev # API server on :3080 (nodemon)
pnpm frontend:dev # Vite client dev server (second terminal)
```
### Full Development (with local router)
Tests and checks:
```bash
# Set your LLM API keys
export ANTHROPIC_API_KEY=your-key
export OPENAI_API_KEY=your-key
# Start full dev stack
make dev-full
```
## Architecture
```
┌─────────────────────────┐ ┌─────────────────────────┐
│ Hanzo Chat UI │────▶│ api.hanzo.ai │
│ (Hanzo Chat) │ │ (or local router) │
│ localhost:3081 │ │ │
└─────────────────────────┘ │ • 100+ AI Models │
│ │ • MCP Tools │
│ │ • Code Execution │
▼ └─────────────────────────┘
┌─────────────────────────┐
│ Local Data Storage │
│ • MongoDB (chat history)│
│ • Meilisearch (search) │
└─────────────────────────┘
pnpm test:all # all workspace tests
pnpm e2e # Playwright end-to-end tests
pnpm lint # ESLint
pnpm format # Prettier
```
## Configuration
### Required Environment Variables
Secrets live in `.env`; the model catalog and endpoints live in `chat.yaml` (copy `chat.example.yaml`). Key variables:
```env
# Your Hanzo API key (required)
OPENAI_API_KEY=sk-hanzo-your-key-here
# API endpoint (default: Hanzo cloud)
OPENAI_BASE_URL=https://api.hanzo.ai/v1
# Features
MCP_ENABLED=true
ALLOW_REGISTRATION=true
HANZO_API_KEY= # Hanzo API key — inference, tools, search
MONGO_URI= # MongoDB connection — chat history, users
JWT_SECRET= # session token signing
CREDS_KEY= # credential encryption
CREDS_IV=
```
### Optional Customization
Sign-in is federated to Hanzo IAM over OpenID Connect (`OPENID_ISSUER=https://hanzo.id`, client `hanzo-chat`).
```env
# Branding
APP_TITLE=My AI Assistant
CUSTOM_FOOTER=Powered by Hanzo AI
## Workspace
# Security
JWT_SECRET=your-secret-key
```
api/ Express backend (:3080) — routes, controllers, Mongoose models
client/ React frontend (Vite)
packages/ data-provider · data-schemas · api · client · agents · mcp
```
## Commands
## Documentation
### Basic Usage
```bash
make up # Start services
make down # Stop services
make logs # View logs
make status # Check health
make clean # Remove all data
```
### Development
```bash
make dev # Dev mode with hot reload
make build # Build containers
make test # Run tests
make lint # Check code quality
make format # Format code
```
### Production
```bash
make prod # Deploy with Traefik
make backup # Backup database
```
## Docker Compose Structure
- `compose.yml` - Base configuration for local development
- `compose.dev.yml` - Development overrides (hot reload, local router)
- `compose.prod.yml` - Production overrides (Traefik, security)
## Features
- 🤖 **100+ AI Models** via Hanzo Router
- 💬 **Clean Chat UI** with modern design
- 🔍 **Full-Text Search** with Meilisearch
- 📝 **Persistent Chat History**
- 🛠️ **MCP Tools** for enhanced capabilities
- 🚀 **Code Execution** via secure runtime
- 🔐 **Enterprise Security** with JWT auth
## Troubleshooting
### Chat not loading
```bash
# Check service status
make status
# View logs
make logs-chat
# Verify API key
echo $OPENAI_API_KEY
```
### Database issues
```bash
# Reset database
make db-reset
# Export data
make db-export
# Import data
make db-import FILE=backup.json
```
## Additional Documentation
- [Production Deployment](./docs/production-domains.md)
- [IAM Integration](./docs/iam-integration.md)
- [Platform Overview](./docs/platform-overview.md)
- [Demo User Guide](./docs/demo-user.md)
## Support
- Documentation: https://docs.hanzo.ai
- Docs: https://hanzo.ai/docs/chat
- Deployment, IAM, and platform notes: [`docs/`](./docs)
- Issues: https://github.com/hanzoai/chat/issues
- Discord: https://discord.gg/hanzoai# CI Test
## License
MIT. Forked from LibreChat (MIT). See [LICENSE](./LICENSE).
+61 -203
View File
@@ -1,227 +1,85 @@
<!-- Last synced with README.md: 2026-03-28 (cae3888) -->
<p align="center"><img src=".github/hero.svg" alt="Hanzo Chat" width="880"></p>
<p align="center">
<a href="https://librechat.ai">
<img src="client/public/assets/logo.svg" height="256">
</a>
<h1 align="center">
<a href="https://librechat.ai">LibreChat</a>
</h1>
</p>
# Hanzo Chat
<p align="center">
<a href="README.md">English</a> ·
<strong>中文</strong>
</p>
Hanzo AI 云的对话入口:多模型对话,内置智能体、工具与检索增强,全部运行在 Hanzo 的后端之上。已上线:[hanzo.chat](https://hanzo.chat)。
<p align="center">
<a href="https://discord.librechat.ai">
<img
src="https://img.shields.io/discord/1086345563026489514?label=&logo=discord&style=for-the-badge&logoWidth=20&logoColor=white&labelColor=000000&color=blueviolet">
</a>
<a href="https://www.youtube.com/@LibreChat">
<img
src="https://img.shields.io/badge/YOUTUBE-red.svg?style=for-the-badge&logo=youtube&logoColor=white&labelColor=000000&logoWidth=20">
</a>
<a href="https://docs.librechat.ai">
<img
src="https://img.shields.io/badge/DOCS-blue.svg?style=for-the-badge&logo=read-the-docs&logoColor=white&labelColor=000000&logoWidth=20">
</a>
<a aria-label="Sponsors" href="https://github.com/sponsors/danny-avila">
<img
src="https://img.shields.io/badge/SPONSORS-brightgreen.svg?style=for-the-badge&logo=github-sponsors&logoColor=white&labelColor=000000&logoWidth=20">
</a>
</p>
Hanzo Chat 与 [hanzo.app](https://hanzo.app)(应用构建器)和 Hanzo 控制台(管理端)互为姊妹产品。所有推理、代码执行与网页搜索都经由统一的 Hanzo API(`api.hanzo.ai/v1`)完成,登录则联合到 Hanzo IAM([hanzo.id](https://hanzo.id))。
<p align="center">
<a href="https://railway.com/deploy/librechat-official?referralCode=HI9hWz&utm_medium=integration&utm_source=readme&utm_campaign=librechat">
<img src="https://railway.com/button.svg" alt="Deploy on Railway" height="30">
</a>
<a href="https://zeabur.com/templates/0X2ZY8">
<img src="https://zeabur.com/button.svg" alt="Deploy on Zeabur" height="30"/>
</a>
<a href="https://template.cloud.sealos.io/deploy?templateName=librechat">
<img src="https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg" alt="Deploy on Sealos" height="30">
</a>
</p>
## 功能
<p align="center">
<a href="https://www.librechat.ai/docs/translation">
<img
src="https://img.shields.io/badge/dynamic/json.svg?style=for-the-badge&color=2096F3&label=locize&query=%24.translatedPercentage&url=https://api.locize.app/badgedata/4cb2598b-ed4d-469c-9b04-2ed531a8cb45&suffix=%+translated"
alt="翻译进度">
</a>
</p>
- **多模型对话** — Zen 系列模型及其他前沿模型,通过 `api.hanzo.ai` 提供服务。
- **智能体** — 在对话中直接构建智能体,或用 `/agent` 命令或 `@提及` 运行你的 Hanzo Cloud 智能体(`/v1/agents`)。
- **MCP 工具** — 接入 Model Context Protocol(模型上下文协议)服务器以调用工具。
- **检索增强(RAG)** — 基于你自己的文件和文档进行对话。
- **网页搜索** — 通过 Hanzo 网页搜索获得有据可循的回答。
- **代码解释器** — 在沙箱运行时中执行代码。
- **图像生成** — 在对话中直接生成图像。
- **访客对话** — 无需注册即可试用免费的 Zen 模型(可选,默认关闭)。
## 环境要求
# ✨ 功能
- Node.js 24(见 `.nvmrc`
- pnpm 10
- Hanzo API 密钥 — 在 [hanzo.ai/dashboard](https://hanzo.ai/dashboard) 获取
- 🖥️ **UI 与体验**:受 ChatGPT 启发,并具备更强的设计与功能。
## 快速开始(Docker
- 🤖 **AI 模型选择**
- Anthropic (Claude), AWS Bedrock, OpenAI, Azure OpenAI, Google, Vertex AI, OpenAI Responses API (包含 Azure)
- [自定义端点 (Custom Endpoints)](https://www.librechat.ai/docs/quick_start/custom_endpoints)LibreChat 支持任何兼容 OpenAI 规范的 API,无需代理。
- 兼容[本地与远程 AI 服务商](https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints)
- Ollama, groq, Cohere, Mistral AI, Apple MLX, koboldcpp, together.ai,
- OpenRouter, Helicone, Perplexity, ShuttleAI, Deepseek, Qwen 等。
```bash
git clone https://github.com/hanzoai/chat.git
cd chat
cp .env.example .env # 填入 HANZO_API_KEY
make up
```
- 🔧 **[代码解释器 (Code Interpreter) API](https://www.librechat.ai/docs/features/code_interpreter)**
- 安全的沙箱执行环境,支持 Python, Node.js (JS/TS), Go, C/C++, Java, PHP, Rust 和 Fortran。
- 无缝文件处理:直接上传、处理并下载文件。
- 隐私无忧:完全隔离且安全的执行环境。
打开 http://localhost:3080。`make up` 会从 `compose.yml` 启动完整技术栈(应用、MongoDB、Meilisearch);`make down` 停止。
- 🔦 **智能体与工具集成**
- **[LibreChat 智能体 (Agents)](https://www.librechat.ai/docs/features/agents)**
- 无代码定制助手:无需编程即可构建专业化的 AI 驱动助手。
- 智能体市场:发现并部署社区构建的智能体。
- 协作共享:与特定用户和群组共享智能体。
- 灵活且可扩展:支持 MCP 服务器、工具、文件搜索、代码执行等。
- 兼容自定义端点、OpenAI, Azure, Anthropic, AWS Bedrock, Google, Vertex AI, Responses API 等。
- [支持模型上下文协议 (MCP)](https://modelcontextprotocol.io/clients#librechat) 用于工具调用。
## 开发
- 🔍 **网页搜索**
- 搜索互联网并检索相关信息以增强 AI 上下文。
- 结合搜索提供商、内容爬虫和结果重排序,确保最佳检索效果。
- **可定制 Jina 重排序**:配置自定义 Jina API URL 用于重排序服务。
- **[了解更多 →](https://www.librechat.ai/docs/features/web_search)**
```bash
pnpm install # 安装工作区依赖
pnpm build:packages # 构建共享的工作区包
pnpm backend:dev # API 服务,端口 :3080nodemon
pnpm frontend:dev # Vite 客户端开发服务器(另开一个终端)
```
- 🪄 **支持代码 Artifacts 的生成式 UI**
- [代码 Artifacts](https://youtu.be/GfTj7O4gmd0?si=WJbdnemZpJzBrJo3) 允许在对话中直接创建 React 组件、HTML 页面和 Mermaid 图表。
测试与检查:
- 🎨 **图像生成与编辑**
- 使用 [GPT-Image-1](https://www.librechat.ai/docs/features/image_gen#1--openai-image-tools-recommended) 进行文生图与图生图。
- 支持 [DALL-E (3/2)](https://www.librechat.ai/docs/features/image_gen#2--dalle-legacy), [Stable Diffusion](https://www.librechat.ai/docs/features/image_gen#3--stable-diffusion-local), [Flux](https://www.librechat.ai/docs/features/image_gen#4--flux) 或任何 [MCP 服务器](https://www.librechat.ai/docs/features/image_gen#5--model-context-protocol-mcp)。
- 根据提示词生成惊艳的视觉效果,或通过指令精修现有图像。
```bash
pnpm test:all # 全部工作区测试
pnpm e2e # Playwright 端到端测试
pnpm lint # ESLint
pnpm format # Prettier
```
- 💾 **预设与上下文管理**
- 创建、保存并分享自定义预设。
- 在对话中随时切换 AI 端点和预设。
- 编辑、重新提交并通过对话分支继续消息。
- 创建并与特定用户和群组共享提示词。
- [消息与对话分叉 (Fork)](https://www.librechat.ai/docs/features/fork) 以实现高级上下文控制。
## 配置
- 💬 **多模态与文件交互**
- 使用 Claude 3, GPT-4.5, GPT-4o, o1, Llama-Vision 和 Gemini 上传并分析图像 📸。
- 支持通过自定义端点、OpenAI, Azure, Anthropic, AWS Bedrock 和 Google 进行文件对话 🗃️。
密钥存放在 `.env` 中;模型目录与端点配置位于 `chat.yaml`(复制 `chat.example.yaml`)。主要变量:
- 🌎 **多语言 UI**
- English, 中文 (简体), 中文 (繁體), العربية, Deutsch, Español, Français, Italiano
- Polski, Português (PT), Português (BR), Русский, 日本語, Svenska, 한국어, Tiếng Việt
- Türkçe, Nederlands, עברית, Català, Čeština, Dansk, Eesti, فارسی
- Suomi, Magyar, Հայերեն, Bahasa Indonesia, ქართული, Latviešu, ไทย, ئۇيغۇرچە
```env
HANZO_API_KEY= # Hanzo API 密钥 — 推理、工具、搜索
MONGO_URI= # MongoDB 连接 — 对话历史、用户
JWT_SECRET= # 会话令牌签名
CREDS_KEY= # 凭据加密
CREDS_IV=
```
- 🧠 **推理 UI**
- 针对 DeepSeek-R1 等思维链/推理 AI 模型的动态推理 UI。
登录通过 OpenID Connect 联合到 Hanzo IAM`OPENID_ISSUER=https://hanzo.id`,客户端 `hanzo-chat`)。
- 🎨 **可定制界面**
- 可定制的下拉菜单和界面,同时适配高级用户和初学者。
## 工作区结构
- 🌊 **[可恢复流 (Resumable Streams)](https://www.librechat.ai/docs/features/resumable_streams)**
- 永不丢失响应:AI 响应在连接中断后自动重连并继续。
- 多标签页与多设备同步:在多个标签页打开同一对话,或在另一设备上继续。
- 生产级可靠性:支持从单机部署到基于 Redis 的水平扩展。
```
api/ Express 后端(:3080)— 路由、控制器、Mongoose 模型
client/ React 前端(Vite
packages/ data-provider · data-schemas · api · client · agents · mcp
```
- 🗣️ **语音与音频**
- 通过语音转文字和文字转语音实现免提对话。
- 自动发送并播放音频。
- 支持 OpenAI, Azure OpenAI 和 Elevenlabs。
## 文档
- 📥 **导入与导出对话**
- 从 LibreChat, ChatGPT, Chatbot UI 导入对话。
- 将对话导出为截图、Markdown、文本、JSON。
- 文档:https://hanzo.ai/docs/chat
- 部署、IAM 与平台说明:[`docs/`](./docs)
- 问题反馈:https://github.com/hanzoai/chat/issues
- 🔍 **搜索与发现**
- 搜索所有消息和对话。
## 许可证
- 👥 **多用户与安全访问**
- 支持 OAuth2, LDAP 和电子邮件登录的多用户安全认证。
- 内置审核系统和 Token 消耗管理工具。
- ⚙️ **配置与部署**
- 支持代理、反向代理、Docker 及多种部署选项。
- 可完全本地运行或部署在云端。
- 📖 **开源与社区**
- 完全开源且在公众监督下开发。
- 社区驱动的开发、支持与反馈。
[查看我们的文档了解更多功能详情](https://docs.librechat.ai/) 📚
## 🪶 LibreChat:全方位的 AI 对话平台
LibreChat 是一个自托管的 AI 对话平台,在一个注重隐私的统一界面中整合了所有主流 AI 服务商。
除了对话功能外,LibreChat 还提供 AI 智能体、模型上下文协议 (MCP) 支持、Artifacts、代码解释器、自定义操作、对话搜索,以及企业级多用户认证。
开源、活跃开发中,专为重视 AI 基础设施自主可控的用户而构建。
---
## 🌐 资源
**GitHub 仓库:**
- **RAG API:** [github.com/danny-avila/rag_api](https://github.com/danny-avila/rag_api)
- **网站:** [github.com/LibreChat-AI/librechat.ai](https://github.com/LibreChat-AI/librechat.ai)
**其他:**
- **官方网站:** [librechat.ai](https://librechat.ai)
- **帮助文档:** [librechat.ai/docs](https://librechat.ai/docs)
- **博客:** [librechat.ai/blog](https://librechat.ai/blog)
---
## 📝 更新日志
访问发布页面和更新日志以了解最新动态:
- [发布页面 (Releases)](https://github.com/danny-avila/LibreChat/releases)
- [更新日志 (Changelog)](https://www.librechat.ai/changelog)
**⚠️ 在更新前请务必查看[更新日志](https://www.librechat.ai/changelog)以了解破坏性更改。**
---
## ⭐ Star 历史
<p align="center">
<a href="https://star-history.com/#danny-avila/LibreChat&Date">
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=danny-avila/LibreChat&type=Date&theme=dark" onerror="this.src='https://api.star-history.com/svg?repos=danny-avila/LibreChat&type=Date'" />
</a>
</p>
<p align="center">
<a href="https://trendshift.io/repositories/4685" target="_blank" style="padding: 10px;">
<img src="https://trendshift.io/api/badge/repositories/4685" alt="danny-avila%2FLibreChat | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/>
</a>
<a href="https://runacap.com/ross-index/q1-24/" target="_blank" rel="noopener" style="margin-left: 20px;">
<img style="width: 260px; height: 56px" src="https://runacap.com/wp-content/uploads/2024/04/ROSS_badge_white_Q1_2024.svg" alt="ROSS Index - 2024年第一季度增长最快的开源初创公司 | Runa Capital" width="260" height="56"/>
</a>
</p>
---
## ✨ 贡献
欢迎任何形式的贡献、建议、错误报告和修复!
对于新功能、组件或扩展,请在发送 PR 前开启 issue 进行讨论。
如果您想帮助我们将 LibreChat 翻译成您的母语,我们非常欢迎!改进翻译不仅能让全球用户更轻松地使用 LibreChat,还能提升整体用户体验。请查看我们的[翻译指南](https://www.librechat.ai/docs/translation)。
---
## 💖 感谢所有贡献者
<a href="https://github.com/danny-avila/LibreChat/graphs/contributors">
<img src="https://contrib.rocks/image?repo=danny-avila/LibreChat" />
</a>
---
## 🎉 特别鸣谢
感谢 [Locize](https://locize.com) 提供的翻译管理工具,支持 LibreChat 的多语言功能。
<p align="center">
<a href="https://locize.com" target="_blank" rel="noopener noreferrer">
<img src="https://github.com/user-attachments/assets/d6b70894-6064-475e-bb65-92a9e23e0077" alt="Locize Logo" height="50">
</a>
</p>
MIT 许可证。基于 LibreChatMIT)分支开发。见 [LICENSE](./LICENSE)。
+3 -3
View File
@@ -1,6 +1,6 @@
const crypto = require('crypto');
const fetch = require('node-fetch');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const {
countTokens,
getBalanceConfig,
@@ -20,7 +20,7 @@ const {
isAgentsEndpoint,
isEphemeralAgentId,
supportsBalanceCheck,
} = require('librechat-data-provider');
} = require('@hanzochat/data-provider');
const {
updateMessage,
getMessages,
@@ -76,7 +76,7 @@ class BaseClient {
this.fetchedConvo;
/** @type {TMessage[]} */
this.currentMessages = [];
/** @type {import('librechat-data-provider').VisionModes | undefined} */
/** @type {import('@hanzochat/data-provider').VisionModes | undefined} */
this.visionMode;
}
+3 -3
View File
@@ -1,9 +1,9 @@
const { z } = require('zod');
const axios = require('axios');
const { Ollama } = require('ollama');
const { sleep } = require('@librechat/agents');
const { logger } = require('@librechat/data-schemas');
const { Constants } = require('librechat-data-provider');
const { sleep } = require('@hanzochat/agents');
const { logger } = require('@hanzochat/data-schemas');
const { Constants } = require('@hanzochat/data-provider');
const { resolveHeaders, deriveBaseURL } = require('@hanzochat/api');
const ollamaPayloadSchema = z.object({
+1 -1
View File
@@ -1,5 +1,5 @@
const { Readable } = require('stream');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
class TextStream extends Readable {
constructor(text, options = {}) {
+1 -1
View File
@@ -1,5 +1,5 @@
const dedent = require('dedent');
const { EModelEndpoint, ArtifactModes } = require('librechat-data-provider');
const { EModelEndpoint, ArtifactModes } = require('@hanzochat/data-provider');
const { generateShadcnPrompt } = require('~/app/clients/prompts/shadcn-docs/generate');
const { components } = require('~/app/clients/prompts/shadcn-docs/components');
@@ -1,5 +1,5 @@
const axios = require('axios');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { isEnabled, generateShortLivedToken } = require('@hanzochat/api');
const footer = `Use the context as your learned knowledge to better answer the user.
@@ -1,5 +1,5 @@
const { ToolMessage } = require('@langchain/core/messages');
const { ContentTypes } = require('librechat-data-provider');
const { ContentTypes } = require('@hanzochat/data-provider');
const { HumanMessage, AIMessage, SystemMessage } = require('@langchain/core/messages');
const { formatAgentMessages } = require('./formatMessages');
+1 -1
View File
@@ -1,5 +1,5 @@
const { ToolMessage } = require('@langchain/core/messages');
const { EModelEndpoint, ContentTypes } = require('librechat-data-provider');
const { EModelEndpoint, ContentTypes } = require('@hanzochat/data-provider');
const { HumanMessage, AIMessage, SystemMessage } = require('@langchain/core/messages');
/**
@@ -1,4 +1,4 @@
const { Constants } = require('librechat-data-provider');
const { Constants } = require('@hanzochat/data-provider');
const { HumanMessage, AIMessage, SystemMessage } = require('@langchain/core/messages');
const { formatMessage, formatLangChainMessages, formatFromLangChain } = require('./formatMessages');
+3 -3
View File
@@ -1,4 +1,4 @@
const { Constants } = require('librechat-data-provider');
const { Constants } = require('@hanzochat/data-provider');
const { initializeFakeClient } = require('./FakeClient');
jest.mock('~/db/connect');
@@ -40,8 +40,8 @@ jest.mock('~/models', () => ({
const { getConvo, saveConvo } = require('~/models');
jest.mock('@librechat/agents', () => {
const actual = jest.requireActual('@librechat/agents');
jest.mock('@hanzochat/agents', () => {
const actual = jest.requireActual('@hanzochat/agents');
return {
...actual,
ChatOpenAI: jest.fn().mockImplementation(() => {
@@ -1,5 +1,5 @@
const { Tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { SearchClient, AzureKeyCredential } = require('@azure/search-documents');
const azureAISearchJsonSchema = {
+2 -2
View File
@@ -3,9 +3,9 @@ const OpenAI = require('openai');
const { v4: uuidv4 } = require('uuid');
const { ProxyAgent, fetch } = require('undici');
const { Tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { getImageBasename, extractBaseURL } = require('@hanzochat/api');
const { FileContext, ContentTypes } = require('librechat-data-provider');
const { FileContext, ContentTypes } = require('@hanzochat/data-provider');
const dalle3JsonSchema = {
type: 'object',
+2 -2
View File
@@ -2,9 +2,9 @@ const axios = require('axios');
const fetch = require('node-fetch');
const { v4: uuidv4 } = require('uuid');
const { Tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { HttpsProxyAgent } = require('https-proxy-agent');
const { FileContext, ContentTypes } = require('librechat-data-provider');
const { FileContext, ContentTypes } = require('@hanzochat/data-provider');
const fluxApiJsonSchema = {
type: 'object',
@@ -5,13 +5,13 @@ const { v4 } = require('uuid');
const { ProxyAgent } = require('undici');
const { GoogleGenAI } = require('@google/genai');
const { tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const {
FileContext,
ContentTypes,
FileSources,
EImageOutputType,
} = require('librechat-data-provider');
} = require('@hanzochat/data-provider');
const {
geminiToolkit,
loadServiceKey,
@@ -4,9 +4,9 @@ const OpenAI = require('openai');
const FormData = require('form-data');
const { ProxyAgent } = require('undici');
const { tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { HttpsProxyAgent } = require('https-proxy-agent');
const { ContentTypes, EImageOutputType } = require('librechat-data-provider');
const { ContentTypes, EImageOutputType } = require('@hanzochat/data-provider');
const { logAxiosError, oaiToolkit, extractBaseURL } = require('@hanzochat/api');
const { getStrategyFunctions } = require('~/server/services/Files/strategies');
const { getFiles } = require('~/models');
@@ -5,8 +5,8 @@ const axios = require('axios');
const sharp = require('sharp');
const { v4: uuidv4 } = require('uuid');
const { Tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { FileContext, ContentTypes } = require('librechat-data-provider');
const { logger } = require('@hanzochat/data-schemas');
const { FileContext, ContentTypes } = require('@hanzochat/data-provider');
const { getBasePath } = require('@hanzochat/api');
const paths = require('~/config/paths');
@@ -1,5 +1,5 @@
const { Tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { getEnvironmentVariable } = require('@langchain/core/utils/env');
const traversaalSearchJsonSchema = {
+1 -1
View File
@@ -1,7 +1,7 @@
/* eslint-disable no-useless-escape */
const axios = require('axios');
const { Tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const wolframJsonSchema = {
type: 'object',
@@ -1,9 +1,9 @@
const OpenAI = require('openai');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const DALLE3 = require('../DALLE3');
jest.mock('openai');
jest.mock('@librechat/data-schemas', () => {
jest.mock('@hanzochat/data-schemas', () => {
return {
logger: {
info: jest.fn(),
@@ -12,8 +12,8 @@ const axios = require('axios');
const OpenAI = require('openai');
const undici = require('undici');
const fetch = require('node-fetch');
const { ContentTypes } = require('librechat-data-provider');
const { ToolMessage } = require('@librechat/agents/langchain/messages');
const { ContentTypes } = require('@hanzochat/data-provider');
const { ToolMessage } = require('@hanzochat/agents/langchain/messages');
const StableDiffusionAPI = require('../StableDiffusion');
const FluxAPI = require('../FluxAPI');
const DALLE3 = require('../DALLE3');
@@ -25,7 +25,7 @@ jest.mock('undici', () => ({
ProxyAgent: jest.fn(),
fetch: jest.fn(),
}));
jest.mock('@librechat/data-schemas', () => ({
jest.mock('@hanzochat/data-schemas', () => ({
logger: { info: jest.fn(), warn: jest.fn(), debug: jest.fn(), error: jest.fn() },
}));
jest.mock('path', () => ({
+3 -3
View File
@@ -1,8 +1,8 @@
const axios = require('axios');
const { tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { generateShortLivedToken } = require('@hanzochat/api');
const { Tools, EToolResources } = require('librechat-data-provider');
const { Tools, EToolResources } = require('@hanzochat/data-provider');
const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions');
const { getFiles } = require('~/models');
@@ -97,7 +97,7 @@ const createFileSearchTool = async ({ userId, files, entity_id, fileCitations =
}
/**
* @param {import('librechat-data-provider').TFile} file
* @param {import('@hanzochat/data-provider').TFile} file
* @returns {{ file_id: string, query: string, k: number, entity_id?: string }}
*/
const createQueryBody = (file) => {
+3 -3
View File
@@ -1,10 +1,10 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const {
EnvVar,
Calculator,
createSearchTool,
createCodeExecutionTool,
} = require('@librechat/agents');
} = require('@hanzochat/agents');
const {
checkAccess,
createSafeUser,
@@ -22,7 +22,7 @@ const {
Permissions,
EToolResources,
PermissionTypes,
} = require('librechat-data-provider');
} = require('@hanzochat/data-provider');
const {
availableTools,
manifestToolMap,
@@ -30,7 +30,7 @@ jest.mock('~/server/services/Config', () => ({
}),
}));
const { Calculator } = require('@librechat/agents');
const { Calculator } = require('@hanzochat/agents');
const { User } = require('~/db/models');
const PluginService = require('~/server/services/PluginService');
+2 -2
View File
@@ -1,6 +1,6 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { isEnabled, math } = require('@hanzochat/api');
const { ViolationTypes } = require('librechat-data-provider');
const { ViolationTypes } = require('@hanzochat/data-provider');
const { deleteAllUserSessions } = require('~/models');
const { removePorts } = require('~/server/utils');
const getLogStores = require('./getLogStores');
+1 -1
View File
@@ -1,5 +1,5 @@
const { isEnabled } = require('@hanzochat/api');
const { Time, CacheKeys } = require('librechat-data-provider');
const { Time, CacheKeys } = require('@hanzochat/data-provider');
const getLogStores = require('./getLogStores');
const { USE_REDIS, LIMIT_CONCURRENT_MESSAGES } = process.env ?? {};
+1 -1
View File
@@ -1,5 +1,5 @@
const { Keyv } = require('keyv');
const { Time, CacheKeys, ViolationTypes } = require('librechat-data-provider');
const { Time, CacheKeys, ViolationTypes } = require('@hanzochat/data-provider');
const {
logFile,
keyvMongo,
+1 -1
View File
@@ -1,5 +1,5 @@
const { isEnabled } = require('@hanzochat/api');
const { ViolationTypes } = require('librechat-data-provider');
const { ViolationTypes } = require('@hanzochat/data-provider');
const getLogStores = require('./getLogStores');
const banViolation = require('./banViolation');
+1 -1
View File
@@ -3,7 +3,7 @@ const fs = require('fs');
const ORIGINAL_ENV = process.env;
const mockDataSchemas = () => {
jest.doMock('@librechat/data-schemas', () => ({
jest.doMock('@hanzochat/data-schemas', () => ({
getTenantId: jest.fn(),
getUserId: jest.fn(),
getRequestId: jest.fn(),
+1 -1
View File
@@ -1,5 +1,5 @@
const { EventSource } = require('eventsource');
const { Time } = require('librechat-data-provider');
const { Time } = require('@hanzochat/data-provider');
const {
MCPManager,
FlowStateManager,
+3 -3
View File
@@ -6,13 +6,13 @@ require('winston-daily-rotate-file');
/**
* Determine the log directory.
* Priority:
* 1. LIBRECHAT_LOG_DIR environment variable (allows user override)
* 1. CHAT_LOG_DIR environment variable (allows user override)
* 2. /app/logs if running in Docker (bind-mounted with correct permissions)
* 3. api/logs relative to this file (local development)
*/
const getLogDir = () => {
if (process.env.LIBRECHAT_LOG_DIR) {
return process.env.LIBRECHAT_LOG_DIR;
if (process.env.CHAT_LOG_DIR) {
return process.env.CHAT_LOG_DIR;
}
// Check if running in Docker container (cwd is /app)
+3 -3
View File
@@ -7,13 +7,13 @@ const { redactFormat, redactMessage, debugTraverse, jsonTruncateFormat } = requi
/**
* Determine the log directory.
* Priority:
* 1. LIBRECHAT_LOG_DIR environment variable (allows user override)
* 1. CHAT_LOG_DIR environment variable (allows user override)
* 2. /app/logs if running in Docker (bind-mounted with correct permissions)
* 3. api/logs relative to this file (local development)
*/
const getLogDir = () => {
if (process.env.LIBRECHAT_LOG_DIR) {
return process.env.LIBRECHAT_LOG_DIR;
if (process.env.CHAT_LOG_DIR) {
return process.env.CHAT_LOG_DIR;
}
// Check if running in Docker container (cwd is /app)
+1 -1
View File
@@ -1,6 +1,6 @@
require('dotenv').config();
const { isEnabled } = require('@hanzochat/api');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const mongoose = require('mongoose');
const MONGO_URI = process.env.MONGO_URI;
+1 -1
View File
@@ -1,5 +1,5 @@
const mongoose = require('mongoose');
const { createModels } = require('@librechat/data-schemas');
const { createModels } = require('@hanzochat/data-schemas');
const { connectDb } = require('./connect');
const indexSync = require('./indexSync');
+1 -1
View File
@@ -4,7 +4,7 @@ describe('api/db/index.js', () => {
const callOrder = [];
jest.mock('@librechat/data-schemas', () => ({
jest.mock('@hanzochat/data-schemas', () => ({
createModels: jest.fn((m) => {
callOrder.push('createModels');
m.models.Message = { name: 'Message' };
+2 -2
View File
@@ -1,7 +1,7 @@
const mongoose = require('mongoose');
const { MeiliSearch } = require('meilisearch');
const { logger } = require('@librechat/data-schemas');
const { CacheKeys } = require('librechat-data-provider');
const { logger } = require('@hanzochat/data-schemas');
const { CacheKeys } = require('@hanzochat/data-provider');
const { isEnabled, FlowStateManager } = require('@hanzochat/api');
const { getLogStores } = require('~/cache');
const { batchResetMeiliFlags } = require('./utils');
+1 -1
View File
@@ -32,7 +32,7 @@ const originalMessageModel = mongoose.models.Message;
const originalConversationModel = mongoose.models.Conversation;
// Mock external modules
jest.mock('@librechat/data-schemas', () => ({
jest.mock('@hanzochat/data-schemas', () => ({
logger: mockLogger,
}));
+1 -1
View File
@@ -1,5 +1,5 @@
const mongoose = require('mongoose');
const { createModels } = require('@librechat/data-schemas');
const { createModels } = require('@hanzochat/data-schemas');
const models = createModels(mongoose);
module.exports = { ...models };
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
+1 -1
View File
@@ -392,7 +392,7 @@ describe('batchResetMeiliFlags', () => {
beforeEach(() => {
// Mock logger.warn to track warning calls
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
warnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {});
});
+5 -5
View File
@@ -1,6 +1,6 @@
const mongoose = require('mongoose');
const crypto = require('node:crypto');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { getCustomEndpointConfig } = require('@hanzochat/api');
const {
Tools,
@@ -10,8 +10,8 @@ const {
isAgentsEndpoint,
isEphemeralAgentId,
encodeEphemeralAgentId,
} = require('librechat-data-provider');
const { mcp_all, mcp_delimiter } = require('librechat-data-provider').Constants;
} = require('@hanzochat/data-provider');
const { mcp_all, mcp_delimiter } = require('@hanzochat/data-provider').Constants;
const {
removeAgentFromAllProjects,
removeAgentIdsFromProject,
@@ -96,7 +96,7 @@ const getAgents = async (searchParameter) => await Agent.find(searchParameter).l
* @param {string} params.spec
* @param {string} params.agent_id
* @param {string} params.endpoint
* @param {import('@librechat/agents').ClientOptions} [params.model_parameters]
* @param {import('@hanzochat/agents').ClientOptions} [params.model_parameters]
* @returns {Promise<Agent|null>} The agent document as a plain object, or null if not found.
*/
const loadEphemeralAgent = async ({ req, spec, endpoint, model_parameters: _m }) => {
@@ -189,7 +189,7 @@ const loadEphemeralAgent = async ({ req, spec, endpoint, model_parameters: _m })
* @param {string} params.spec
* @param {string} params.agent_id
* @param {string} params.endpoint
* @param {import('@librechat/agents').ClientOptions} [params.model_parameters]
* @param {import('@hanzochat/agents').ClientOptions} [params.model_parameters]
* @returns {Promise<Agent|null>} The agent document as a plain object, or null if not found.
*/
const loadAgent = async ({ req, spec, agent_id, endpoint, model_parameters }) => {
+11 -11
View File
@@ -13,9 +13,9 @@ jest.mock('~/server/services/Config', () => ({
const mongoose = require('mongoose');
const { v4: uuidv4 } = require('uuid');
const { agentSchema } = require('@librechat/data-schemas');
const { agentSchema } = require('@hanzochat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
const { AccessRoleIds, ResourceType, PrincipalType } = require('librechat-data-provider');
const { AccessRoleIds, ResourceType, PrincipalType } = require('@hanzochat/data-provider');
const {
getAgent,
loadAgent,
@@ -35,7 +35,7 @@ const { getCachedTools, getMCPServerTools } = require('~/server/services/Config'
const { AclEntry, User } = require('~/db/models');
/**
* @type {import('mongoose').Model<import('@librechat/data-schemas').IAgent>}
* @type {import('mongoose').Model<import('@hanzochat/data-schemas').IAgent>}
*/
let Agent;
@@ -1111,7 +1111,7 @@ describe('models/Agent', () => {
const agentId = 'ephemeral_test';
const endpoint = 'openai';
const originalModule = jest.requireActual('librechat-data-provider');
const originalModule = jest.requireActual('@hanzochat/data-provider');
const mockDataProvider = {
...originalModule,
@@ -1121,12 +1121,12 @@ describe('models/Agent', () => {
},
};
jest.doMock('librechat-data-provider', () => mockDataProvider);
jest.doMock('@hanzochat/data-provider', () => mockDataProvider);
expect(agentId).toBeDefined();
expect(endpoint).toBeDefined();
jest.dontMock('librechat-data-provider');
jest.dontMock('@hanzochat/data-provider');
});
test('should handle loadAgent functionality and errors', async () => {
@@ -2391,7 +2391,7 @@ describe('models/Agent', () => {
});
test('should test ephemeral agent loading logic', async () => {
const { EPHEMERAL_AGENT_ID } = require('librechat-data-provider').Constants;
const { EPHEMERAL_AGENT_ID } = require('@hanzochat/data-provider').Constants;
getCachedTools.mockResolvedValue({
tool1_mcp_server1: {},
@@ -2514,7 +2514,7 @@ describe('models/Agent', () => {
});
test('should handle ephemeral agent with no MCP servers', async () => {
const { EPHEMERAL_AGENT_ID } = require('librechat-data-provider').Constants;
const { EPHEMERAL_AGENT_ID } = require('@hanzochat/data-provider').Constants;
getCachedTools.mockResolvedValue({});
@@ -2546,7 +2546,7 @@ describe('models/Agent', () => {
});
test('should handle ephemeral agent with undefined ephemeralAgent in body', async () => {
const { EPHEMERAL_AGENT_ID } = require('librechat-data-provider').Constants;
const { EPHEMERAL_AGENT_ID } = require('@hanzochat/data-provider').Constants;
getCachedTools.mockResolvedValue({});
@@ -2584,7 +2584,7 @@ describe('models/Agent', () => {
});
test('should handle ephemeral agent with extremely large tool list', async () => {
const { EPHEMERAL_AGENT_ID } = require('librechat-data-provider').Constants;
const { EPHEMERAL_AGENT_ID } = require('@hanzochat/data-provider').Constants;
const largeToolList = Array.from({ length: 100 }, (_, i) => `tool_${i}_mcp_server1`);
const availableTools = largeToolList.reduce((acc, tool) => {
@@ -3123,7 +3123,7 @@ describe('models/Agent', () => {
});
test('should handle loadEphemeralAgent with malformed MCP tool names', async () => {
const { EPHEMERAL_AGENT_ID } = require('librechat-data-provider').Constants;
const { EPHEMERAL_AGENT_ID } = require('@hanzochat/data-provider').Constants;
getCachedTools.mockResolvedValue({
malformed_tool_name: {}, // No mcp delimiter
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { Banner } = require('~/db/models');
/**
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const options = [
{
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { createTempChatExpirationDate } = require('@hanzochat/api');
const { getMessages, deleteMessages } = require('./Message');
const { Conversation } = require('~/db/models');
+1 -1
View File
@@ -1,6 +1,6 @@
const mongoose = require('mongoose');
const { v4: uuidv4 } = require('uuid');
const { EModelEndpoint } = require('librechat-data-provider');
const { EModelEndpoint } = require('@hanzochat/data-provider');
const { MongoMemoryServer } = require('mongodb-memory-server');
const {
deleteNullOrEmptyConversations,
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { ConversationTag, Conversation } = require('~/db/models');
/**
+2 -2
View File
@@ -1,5 +1,5 @@
const { logger } = require('@librechat/data-schemas');
const { EToolResources, FileContext } = require('librechat-data-provider');
const { logger } = require('@hanzochat/data-schemas');
const { EToolResources, FileContext } = require('@hanzochat/data-provider');
const { File } = require('~/db/models');
/**
+2 -2
View File
@@ -1,13 +1,13 @@
const mongoose = require('mongoose');
const { v4: uuidv4 } = require('uuid');
const { MongoMemoryServer } = require('mongodb-memory-server');
const { createModels, createMethods } = require('@librechat/data-schemas');
const { createModels, createMethods } = require('@hanzochat/data-schemas');
const {
SystemRoles,
ResourceType,
AccessRoleIds,
PrincipalType,
} = require('librechat-data-provider');
} = require('@hanzochat/data-provider');
const { grantPermission } = require('~/server/services/PermissionService');
const { createAgent } = require('./Agent');
+1 -1
View File
@@ -1,5 +1,5 @@
const { z } = require('zod');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { createTempChatExpirationDate } = require('@hanzochat/api');
const { Message } = require('~/db/models');
+2 -2
View File
@@ -1,6 +1,6 @@
const mongoose = require('mongoose');
const { v4: uuidv4 } = require('uuid');
const { messageSchema } = require('@librechat/data-schemas');
const { messageSchema } = require('@hanzochat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
const {
@@ -16,7 +16,7 @@ const {
jest.mock('~/server/services/Config/app');
/**
* @type {import('mongoose').Model<import('@librechat/data-schemas').IMessage>}
* @type {import('mongoose').Model<import('@hanzochat/data-schemas').IMessage>}
*/
let Message;
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { Preset } = require('~/db/models');
const getPreset = async (user, presetId) => {
+1 -1
View File
@@ -1,4 +1,4 @@
const { GLOBAL_PROJECT_NAME } = require('librechat-data-provider').Constants;
const { GLOBAL_PROJECT_NAME } = require('@hanzochat/data-provider').Constants;
const { Project } = require('~/db/models');
/**
+2 -2
View File
@@ -1,7 +1,7 @@
const { ObjectId } = require('mongodb');
const { escapeRegExp } = require('@hanzochat/api');
const { logger } = require('@librechat/data-schemas');
const { SystemRoles, ResourceType, SystemCategories } = require('librechat-data-provider');
const { logger } = require('@hanzochat/data-schemas');
const { SystemRoles, ResourceType, SystemCategories } = require('@hanzochat/data-provider');
const {
getSoleOwnedResourceIds,
removeAllPermissions,
+2 -2
View File
@@ -1,6 +1,6 @@
const mongoose = require('mongoose');
const { ObjectId } = require('mongodb');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
const {
SystemRoles,
@@ -8,7 +8,7 @@ const {
AccessRoleIds,
PrincipalType,
PermissionBits,
} = require('librechat-data-provider');
} = require('@hanzochat/data-provider');
// Mock the config/connect module to prevent connection attempts during tests
jest.mock('../../config/connect', () => jest.fn().mockResolvedValue(true));
+2 -2
View File
@@ -1,6 +1,6 @@
const mongoose = require('mongoose');
const { ObjectId } = require('mongodb');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
const {
Constants,
@@ -9,7 +9,7 @@ const {
PrincipalType,
PrincipalModel,
PermissionBits,
} = require('librechat-data-provider');
} = require('@hanzochat/data-provider');
// Mock the config/connect module to prevent connection attempts during tests
jest.mock('../../config/connect', () => jest.fn().mockResolvedValue(true));
+2 -2
View File
@@ -3,8 +3,8 @@ const {
roleDefaults,
permissionsSchema,
removeNullishValues,
} = require('librechat-data-provider');
const { logger } = require('@librechat/data-schemas');
} = require('@hanzochat/data-provider');
const { logger } = require('@hanzochat/data-schemas');
const getLogStores = require('~/cache/getLogStores');
const { Role } = require('~/db/models');
+1 -1
View File
@@ -5,7 +5,7 @@ const {
Permissions,
roleDefaults,
PermissionTypes,
} = require('librechat-data-provider');
} = require('@hanzochat/data-provider');
const { getRoleByName, updateAccessPermissions } = require('~/models/Role');
const getLogStores = require('~/cache/getLogStores');
const { initializeRoles } = require('~/models');
+2 -2
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { getMultiplier, getCacheMultiplier } = require('./tx');
const { Transaction, Balance } = require('~/db/models');
@@ -12,7 +12,7 @@ const cancelRate = 1.15;
* @param {Object} params - The function parameters.
* @param {string|mongoose.Types.ObjectId} params.user - The user ID.
* @param {number} params.incrementValue - The value to increment the balance by (can be negative).
* @param {import('mongoose').UpdateQuery<import('@librechat/data-schemas').IBalance>['$set']} [params.setValues] - Optional additional fields to set.
* @param {import('mongoose').UpdateQuery<import('@hanzochat/data-schemas').IBalance>['$set']} [params.setValues] - Optional additional fields to set.
* @returns {Promise<Object>} Returns the updated balance document (lean).
* @throws {Error} Throws an error if the update fails after multiple retries.
*/
+3 -3
View File
@@ -1,5 +1,5 @@
const { logger } = require('@librechat/data-schemas');
const { ViolationTypes } = require('librechat-data-provider');
const { logger } = require('@hanzochat/data-schemas');
const { ViolationTypes } = require('@hanzochat/data-provider');
const { createAutoRefillTransaction } = require('./Transaction');
const { logViolation } = require('~/cache');
const { getMultiplier } = require('./tx');
@@ -200,7 +200,7 @@ const checkBalanceRecord = async function ({
addIntervalToDate(lastRefillDate, record.refillIntervalValue, record.refillIntervalUnit)
) {
try {
/** @type {{ rate: number, user: string, balance: number, transaction: import('@librechat/data-schemas').ITransaction}} */
/** @type {{ rate: number, user: string, balance: number, transaction: import('@hanzochat/data-schemas').ITransaction}} */
const result = await createAutoRefillTransaction({
user: user,
tokenType: 'credits',
+2 -2
View File
@@ -9,7 +9,7 @@ const mockClient = {
isModelAllowed: jest.fn(),
};
jest.mock('@librechat/data-schemas', () => ({
jest.mock('@hanzochat/data-schemas', () => ({
logger: { info: jest.fn(), warn: jest.fn(), error: jest.fn(), debug: jest.fn() },
}));
jest.mock('~/server/services/CommerceClient', () => ({
@@ -19,7 +19,7 @@ jest.mock('~/cache', () => ({ logViolation: jest.fn().mockResolvedValue(undefine
jest.mock('./tx', () => ({ getMultiplier: () => 1 }));
jest.mock('./Transaction', () => ({ createAutoRefillTransaction: jest.fn() }));
jest.mock('~/db/models', () => ({ Balance: { findOne: jest.fn() } }));
jest.mock('librechat-data-provider', () => ({
jest.mock('@hanzochat/data-provider', () => ({
ViolationTypes: { TOKEN_BALANCE: 'token_balance' },
}));
+1 -1
View File
@@ -1,5 +1,5 @@
const mongoose = require('mongoose');
const { buildTree } = require('librechat-data-provider');
const { buildTree } = require('@hanzochat/data-provider');
const { MongoMemoryServer } = require('mongodb-memory-server');
const { getMessages, bulkSaveMessages } = require('./Message');
const { Message } = require('~/db/models');
+1 -1
View File
@@ -1,5 +1,5 @@
const mongoose = require('mongoose');
const { createMethods } = require('@librechat/data-schemas');
const { createMethods } = require('@hanzochat/data-schemas');
const methods = createMethods(mongoose);
const { comparePassword } = require('./userMethods');
const {
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { updateInterfacePermissions: updateInterfacePerms } = require('@hanzochat/api');
const { getRoleByName, updateAccessPermissions } = require('./Role');
+1 -1
View File
@@ -1,5 +1,5 @@
const mongoose = require('mongoose');
const { logger, hashToken, getRandomValues } = require('@librechat/data-schemas');
const { logger, hashToken, getRandomValues } = require('@hanzochat/data-schemas');
const { createToken, findToken } = require('~/models');
/**
+6 -6
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { getCustomEndpointConfig } = require('@hanzochat/api');
const {
Tools,
@@ -7,7 +7,7 @@ const {
isEphemeralAgentId,
appendAgentIdSuffix,
encodeEphemeralAgentId,
} = require('librechat-data-provider');
} = require('@hanzochat/data-provider');
const { getMCPServerTools } = require('~/server/services/Config');
const { mcp_all, mcp_delimiter } = Constants;
@@ -21,7 +21,7 @@ const ADDED_AGENT_ID = 'added_agent';
* Get an agent document based on the provided ID.
* @param {Object} searchParameter - The search parameters to find the agent.
* @param {string} searchParameter.id - The ID of the agent.
* @returns {Promise<import('librechat-data-provider').Agent|null>}
* @returns {Promise<import('@hanzochat/data-provider').Agent|null>}
*/
let getAgent;
@@ -39,9 +39,9 @@ const setGetAgent = (fn) => {
*
* @param {Object} params
* @param {import('express').Request} params.req
* @param {import('librechat-data-provider').TConversation} params.conversation - The added conversation
* @param {import('librechat-data-provider').Agent} [params.primaryAgent] - The primary agent (used to duplicate tools when both are ephemeral)
* @returns {Promise<import('librechat-data-provider').Agent|null>} The agent config as a plain object, or null if invalid.
* @param {import('@hanzochat/data-provider').TConversation} params.conversation - The added conversation
* @param {import('@hanzochat/data-provider').Agent} [params.primaryAgent] - The primary agent (used to duplicate tools when both are ephemeral)
* @returns {Promise<import('@hanzochat/data-provider').Agent|null>} The agent config as a plain object, or null if invalid.
*/
const loadAddedAgent = async ({ req, conversation, primaryAgent }) => {
if (!conversation) {
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { createTransaction, createStructuredTransaction } = require('./Transaction');
/**
* Creates up to two transactions to record the spending of tokens.
+1 -1
View File
@@ -1,6 +1,6 @@
/** Note: No hard-coded values should be used in this file. */
const { maxTokensMap } = require('@hanzochat/api');
const { EModelEndpoint } = require('librechat-data-provider');
const { EModelEndpoint } = require('@hanzochat/data-provider');
const {
defaultRate,
tokenValues,
+3 -3
View File
@@ -44,9 +44,9 @@
"@google/genai": "^1.19.0",
"@keyv/redis": "^4.3.3",
"@langchain/core": "^0.3.80",
"@librechat/agents": "^3.1.51",
"@hanzochat/agents": "^3.2.63",
"@hanzochat/api": "workspace:*",
"@librechat/data-schemas": "workspace:*",
"@hanzochat/data-schemas": "workspace:*",
"@microsoft/microsoft-graph-client": "^3.0.7",
"@modelcontextprotocol/sdk": "1.22.0",
"@node-saml/passport-saml": "^5.1.0",
@@ -78,7 +78,7 @@
"keyv": "^5.3.2",
"keyv-file": "^5.1.2",
"klona": "^2.0.6",
"librechat-data-provider": "workspace:*",
"@hanzochat/data-provider": "workspace:*",
"lodash": "^4.17.23",
"mathjs": "^15.1.0",
"meilisearch": "^0.38.0",
+1 -1
View File
@@ -1,4 +1,4 @@
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
/** WeakMap to hold temporary data associated with requests */
const requestDataMap = new WeakMap();
+1 -1
View File
@@ -1,7 +1,7 @@
const cookies = require('cookie');
const jwt = require('jsonwebtoken');
const openIdClient = require('openid-client');
const { logger } = require('@librechat/data-schemas');
const { logger } = require('@hanzochat/data-schemas');
const { isEnabled, findOpenIDUser } = require('@hanzochat/api');
const {
requestPasswordReset,
@@ -1,4 +1,4 @@
jest.mock('@librechat/data-schemas', () => ({
jest.mock('@hanzochat/data-schemas', () => ({
logger: { error: jest.fn(), debug: jest.fn(), warn: jest.fn() },
}));
jest.mock('~/server/services/GraphTokenService', () => ({

Some files were not shown because too many files have changed in this diff Show More