Compare commits
45
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1eea55929e | ||
|
|
b2aab4aff9 | ||
|
|
3f4addac86 | ||
|
|
f2778c26cb | ||
|
|
12bc51f901 | ||
|
|
dff9f48c17 | ||
|
|
7a24877eaf | ||
|
|
01597b9bb2 | ||
|
|
9c4488d66e | ||
|
|
b237551ffa | ||
|
|
c7f7ef984e | ||
|
|
74954c3f81 | ||
|
|
e9b4c41d2d | ||
|
|
ba0eb6f2d2 | ||
|
|
3bb78e514c | ||
|
|
d4a9b14ba6 | ||
|
|
b49354fd1a | ||
|
|
3759e382f6 | ||
|
|
963399cedc | ||
|
|
6110349085 | ||
|
|
dd8fb7194c | ||
|
|
4448e8d49c | ||
|
|
cb0649e10b | ||
|
|
31af61cb8b | ||
|
|
212ba7d822 | ||
|
|
16745e26fa | ||
|
|
e661f4c0b6 | ||
|
|
9e5e158145 | ||
|
|
c1df3816e3 | ||
|
|
77f768f7fa | ||
|
|
885f6ec33c | ||
|
|
83554c557d | ||
|
|
98d0dad34b | ||
|
|
44956e86b9 | ||
|
|
167108dca5 | ||
|
|
c57194b535 | ||
|
|
6cab482687 | ||
|
|
8b4a7a6b4b | ||
|
|
ca72857533 | ||
|
|
3595b2af22 | ||
|
|
0359f4c8fb | ||
|
|
04d041c2f4 | ||
|
|
3fe63b68d6 | ||
|
|
b6e5d1082b | ||
|
|
1990fa4072 |
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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,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}"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
name: Publish `librechat-data-provider` to NPM
|
||||
name: Publish `@hanzochat/data-provider` to NPM
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 && \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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 }}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
---
|
||||
|
||||
@@ -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/...
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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 服务,端口 :3080(nodemon)
|
||||
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 许可证。基于 LibreChat(MIT)分支开发。见 [LICENSE](./LICENSE)。
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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,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,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');
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,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,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', () => ({
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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,
|
||||
@@ -12,8 +12,8 @@ const {
|
||||
loadWebSearchAuth,
|
||||
buildImageToolContext,
|
||||
buildWebSearchContext,
|
||||
resolveHanzoCloudKey,
|
||||
isHanzoPerUserKeyEnabled,
|
||||
resolveTenantBearer,
|
||||
OPENID_BEARER_SENTINEL,
|
||||
} = require('@hanzochat/api');
|
||||
const { getMCPServersRegistry } = require('~/config');
|
||||
const {
|
||||
@@ -22,7 +22,7 @@ const {
|
||||
Permissions,
|
||||
EToolResources,
|
||||
PermissionTypes,
|
||||
} = require('librechat-data-provider');
|
||||
} = require('@hanzochat/data-provider');
|
||||
const {
|
||||
availableTools,
|
||||
manifestToolMap,
|
||||
@@ -243,18 +243,17 @@ const loadTools = async ({
|
||||
customConstructors.dalle = async () => {
|
||||
const authFields = getAuthFields('dalle');
|
||||
const authValues = await loadAuthValues({ userId: user, authFields });
|
||||
const billingUser = options.req?.user;
|
||||
const isAuthenticatedUser = Boolean(
|
||||
billingUser && !billingUser.guest && billingUser.email,
|
||||
);
|
||||
if (isHanzoPerUserKeyEnabled() && isAuthenticatedUser) {
|
||||
const perUserKey = await resolveHanzoCloudKey(billingUser);
|
||||
if (!perUserKey) {
|
||||
throw new Error(
|
||||
'Your Hanzo Cloud account is not linked for billing yet. Please sign out and back in, then claim your starter credit at https://billing.hanzo.ai',
|
||||
);
|
||||
// Canonical Hanzo Cloud billing (mirrors custom/initialize.ts): when the
|
||||
// image endpoint is configured to forward the user's IAM bearer
|
||||
// (DALLE3_API_KEY === the OIDC-token sentinel), resolve the signed-in
|
||||
// user's own IAM token and forward it so cloud meters THEIR org. Fail
|
||||
// closed if there is no forwardable bearer — no shared key to spend.
|
||||
if (authValues.DALLE3_API_KEY === OPENID_BEARER_SENTINEL) {
|
||||
const bearer = resolveTenantBearer(options.req);
|
||||
if (!bearer) {
|
||||
throw new Error('Sign in with Hanzo to generate images — your Hanzo account funds this request.');
|
||||
}
|
||||
authValues.DALLE3_API_KEY = perUserKey;
|
||||
authValues.DALLE3_API_KEY = bearer;
|
||||
}
|
||||
return new DALLE3({ ...imageGenOptions, ...authValues, userId: user });
|
||||
};
|
||||
|
||||
@@ -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');
|
||||
|
||||
Vendored
+2
-2
@@ -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');
|
||||
|
||||
Vendored
+1
-1
@@ -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 ?? {};
|
||||
|
||||
Vendored
+1
-1
@@ -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,
|
||||
|
||||
Vendored
+1
-1
@@ -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');
|
||||
|
||||
|
||||
@@ -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
@@ -1,5 +1,5 @@
|
||||
const { EventSource } = require('eventsource');
|
||||
const { Time } = require('librechat-data-provider');
|
||||
const { Time } = require('@hanzochat/data-provider');
|
||||
const {
|
||||
MCPManager,
|
||||
FlowStateManager,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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');
|
||||
|
||||
|
||||
@@ -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
@@ -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');
|
||||
|
||||
@@ -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
@@ -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
@@ -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));
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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,4 +1,4 @@
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
const { logger } = require('@hanzochat/data-schemas');
|
||||
const { Banner } = require('~/db/models');
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
const { logger } = require('@hanzochat/data-schemas');
|
||||
|
||||
const options = [
|
||||
{
|
||||
|
||||
@@ -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,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,4 +1,4 @@
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
const { logger } = require('@hanzochat/data-schemas');
|
||||
const { ConversationTag, Conversation } = require('~/db/models');
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -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');
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,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');
|
||||
|
||||
|
||||
@@ -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,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,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');
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
+6
-3
@@ -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');
|
||||
|
||||
@@ -37,7 +37,10 @@ const getRoleByName = async function (roleName, fieldsToSelect = null) {
|
||||
// generation for that role died. roleDefaults[roleName] always carries a
|
||||
// name, so this guard makes the nameless create structurally impossible.
|
||||
if (!role && roleDefaults[roleName]) {
|
||||
role = await new Role(roleDefaults[roleName]).save();
|
||||
// Store-aware: Role resolves to the SQLite DocModel/DualWriteModel under the
|
||||
// CHAT_STORE_SQLITE flip, where `new Role()` throws "Role is not a constructor".
|
||||
// `.create()` is the bounded equivalent; it returns the created doc (toObject).
|
||||
role = await Role.create(roleDefaults[roleName]);
|
||||
await cache.set(roleName, role);
|
||||
return role.toObject();
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
+27
-20
@@ -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.
|
||||
*/
|
||||
@@ -150,6 +150,28 @@ function calculateTokenValue(txn) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists a transaction via the store-aware `Transaction` model (`~/db/models`),
|
||||
* which resolves to the SQLite DocModel / DualWriteModel under the CHAT_STORE_SQLITE
|
||||
* flip — where the mongoose-document constructor (`new Transaction()`) + `.save()`
|
||||
* throws "Transaction is not a constructor". The provided calculator mutates the
|
||||
* working object with the derived fields (rate/tokenValue/rateDetail) BEFORE the
|
||||
* insert, then the non-schema calculator inputs (endpointTokenConfig/inputTokenCount)
|
||||
* and rateDetail are stripped so the persisted document matches the mongoose path
|
||||
* (mongoose drops non-schema paths on save; the document store does not).
|
||||
* @param {object} txData
|
||||
* @param {(txn: object) => void} calculate
|
||||
* @returns {Promise<object>} the created transaction document
|
||||
*/
|
||||
async function persistTransaction(txData, calculate) {
|
||||
const txn = { ...txData };
|
||||
calculate(txn);
|
||||
delete txn.endpointTokenConfig;
|
||||
delete txn.inputTokenCount;
|
||||
delete txn.rateDetail;
|
||||
return Transaction.create(txn);
|
||||
}
|
||||
|
||||
/**
|
||||
* New static method to create an auto-refill transaction that does NOT trigger a balance update.
|
||||
* @param {object} txData - Transaction data.
|
||||
@@ -163,11 +185,7 @@ async function createAutoRefillTransaction(txData) {
|
||||
if (txData.rawAmount != null && isNaN(txData.rawAmount)) {
|
||||
return;
|
||||
}
|
||||
const transaction = new Transaction(txData);
|
||||
transaction.endpointTokenConfig = txData.endpointTokenConfig;
|
||||
transaction.inputTokenCount = txData.inputTokenCount;
|
||||
calculateTokenValue(transaction);
|
||||
await transaction.save();
|
||||
const transaction = await persistTransaction(txData, calculateTokenValue);
|
||||
|
||||
const balanceResponse = await updateBalance({
|
||||
user: transaction.user,
|
||||
@@ -198,12 +216,7 @@ async function createTransaction(_txData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const transaction = new Transaction(txData);
|
||||
transaction.endpointTokenConfig = txData.endpointTokenConfig;
|
||||
transaction.inputTokenCount = txData.inputTokenCount;
|
||||
calculateTokenValue(transaction);
|
||||
|
||||
await transaction.save();
|
||||
const transaction = await persistTransaction(txData, calculateTokenValue);
|
||||
if (!balance?.enabled) {
|
||||
return;
|
||||
}
|
||||
@@ -240,13 +253,7 @@ async function createStructuredTransaction(_txData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const transaction = new Transaction(txData);
|
||||
transaction.endpointTokenConfig = txData.endpointTokenConfig;
|
||||
transaction.inputTokenCount = txData.inputTokenCount;
|
||||
|
||||
calculateStructuredTokenValue(transaction);
|
||||
|
||||
await transaction.save();
|
||||
const transaction = await persistTransaction(txData, calculateStructuredTokenValue);
|
||||
|
||||
if (!balance?.enabled) {
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
const { ViolationTypes } = require('librechat-data-provider');
|
||||
const { billingSubject } = require('@hanzochat/api');
|
||||
const { logger } = require('@hanzochat/data-schemas');
|
||||
const { ViolationTypes } = require('@hanzochat/data-provider');
|
||||
const { createAutoRefillTransaction } = require('./Transaction');
|
||||
const { logViolation } = require('~/cache');
|
||||
const { getMultiplier } = require('./tx');
|
||||
@@ -95,26 +94,12 @@ const checkBalanceRecord = async function ({
|
||||
const multiplier = getMultiplier({ valueKey, tokenType, model, endpoint, endpointTokenConfig });
|
||||
const tokenCost = amount * multiplier;
|
||||
|
||||
// Guests (anonymous preview) are NOT balance-gated here. Their spend is bounded
|
||||
// two ways, neither of which is an authed user's org balance: (1) the per-IP
|
||||
// guest message limiter (GUEST_MESSAGE_MAX, default 3) and (2) the separate,
|
||||
// small-capped, NON-exempt guest key (HANZO_API_KEY) whose own org's Commerce
|
||||
// balance the cloud gateway debits and 402s when empty. Running them through the
|
||||
// Commerce/local gate (startBalance:0) would block the free tier entirely.
|
||||
if (req?.user?.guest === true) {
|
||||
return { canSpend: true, balance: 0, tokenCost };
|
||||
}
|
||||
|
||||
const commerceClient = getCommerceClient();
|
||||
const billingOrg = (req?.user?.organization ?? '').toString().trim();
|
||||
// Per-user billing subject — prefer the one resolveHanzoCloudKey stamped from
|
||||
// the authoritative IAM identity; otherwise derive it from organization + email
|
||||
// (name == email for individual signups). This keys the gate on the SAME
|
||||
// account the gateway debits (per-user for the shared "hanzo" catch-all), not
|
||||
// the shared org balance.
|
||||
const subject =
|
||||
(req?.user?.billingSubject ?? '').toString().trim() ||
|
||||
billingSubject(billingOrg, req?.user?.email);
|
||||
// Tenant billing key = the org (the token `owner`). cloud is the authoritative
|
||||
// meter+gate and bills per-org (see AUTH_BILLING_CONTRACT.md); this optional
|
||||
// local pre-flight keys on the SAME org so it never diverges from cloud. This
|
||||
// gate is OFF in production (balance.enabled=false) — cloud is the ONE gate.
|
||||
const subject = (req?.user?.organization ?? '').toString().trim();
|
||||
|
||||
// Commerce-first authoritative gate (per-subject, fail closed).
|
||||
if (commerceClient && subject) {
|
||||
@@ -215,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',
|
||||
|
||||
@@ -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,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
@@ -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,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,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');
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,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,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
@@ -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,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,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
Reference in New Issue
Block a user