Skip to content

Commit

Permalink
Merge pull request #2 from e-gineering/upstream_version
Browse files Browse the repository at this point in the history
Upstream version
  • Loading branch information
tmendenhall authored Feb 22, 2024
2 parents 63e8490 + 9806424 commit e16e238
Show file tree
Hide file tree
Showing 388 changed files with 23,269 additions and 7,060 deletions.
19 changes: 17 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ DEBUG_CONSOLE=false
# Endpoints #
#===================================================#

# ENDPOINTS=openAI,azureOpenAI,bingAI,chatGPTBrowser,google,gptPlugins,anthropic
# ENDPOINTS=openAI,assistants,azureOpenAI,bingAI,chatGPTBrowser,google,gptPlugins,anthropic

PROXY=

Expand Down Expand Up @@ -117,6 +117,14 @@ DEBUG_OPENAI=false

# OPENAI_ORGANIZATION=

#====================#
# Assistants API #
#====================#

# ASSISTANTS_API_KEY=
# ASSISTANTS_BASE_URL=
# ASSISTANTS_MODELS=gpt-3.5-turbo-0125,gpt-3.5-turbo-16k-0613,gpt-3.5-turbo-16k,gpt-3.5-turbo,gpt-4,gpt-4-0314,gpt-4-32k-0314,gpt-4-0613,gpt-3.5-turbo-0613,gpt-3.5-turbo-1106,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview

#============#
# OpenRouter #
#============#
Expand Down Expand Up @@ -315,8 +323,15 @@ FIREBASE_APP_ID=

# NODE_ENV=

# If using Redis, you should flush the cache after changing any LibreChat settings
# REDIS_URI=
# USE_REDIS=

# Give the AI Icon a Birthday Hat :)
# Will show automatically on February 11th (LibreChat's birthday)
# Set this to false to disable the birthday hat
# Set to true to enable all the time.
# SHOW_BIRTHDAY_ICON=true

# E2E_USER_EMAIL=
# E2E_USER_PASSWORD=
# E2E_USER_PASSWORD=
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ module.exports = {
},
],
},
{
files: ['./packages/data-provider/specs/**/*.ts'],
parserOptions: {
project: './packages/data-provider/tsconfig.spec.json',
},
},
],
settings: {
react: {
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/backend-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ jobs:
- name: Run unit tests
run: cd api && npm run test:ci

- name: Run librechat-data-provider unit tests
run: cd packages/data-provider && npm run test:ci

- name: Run linters
uses: wearerequired/lint-action@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,4 @@ jobs:
push: true
tags: ${{ steps.meta-librechat.outputs.tags }}
platforms: linux/amd64,linux/arm64
target: node
target: node
23 changes: 22 additions & 1 deletion .github/workflows/dev-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
paths:
- 'api/**'
- 'client/**'
- 'packages/**'

jobs:
build:
Expand All @@ -30,6 +31,13 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Login to Docker Hub
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

# Build Docker images
- name: Build Docker images
run: |
Expand All @@ -38,7 +46,7 @@ jobs:
docker build -f Dockerfile -t librechat-dev .
# Tag and push the images to GitHub Container Registry
- name: Tag and push images
- name: Tag and push images to GHCR
run: |
docker tag librechat-dev-api:latest ghcr.io/${{ github.repository_owner }}/librechat-dev-api:${{ github.sha }}
docker push ghcr.io/${{ github.repository_owner }}/librechat-dev-api:${{ github.sha }}
Expand All @@ -49,3 +57,16 @@ jobs:
docker push ghcr.io/${{ github.repository_owner }}/librechat-dev:${{ github.sha }}
docker tag librechat-dev:latest ghcr.io/${{ github.repository_owner }}/librechat-dev:latest
docker push ghcr.io/${{ github.repository_owner }}/librechat-dev:latest
# Tag and push the images to Docker Hub
- name: Tag and push images to Docker Hub
run: |
docker tag librechat-dev-api:latest ${{ secrets.DOCKERHUB_USERNAME }}/librechat-dev-api:${{ github.sha }}
docker push ${{ secrets.DOCKERHUB_USERNAME }}/librechat-dev-api:${{ github.sha }}
docker tag librechat-dev-api:latest ${{ secrets.DOCKERHUB_USERNAME }}/librechat-dev-api:latest
docker push ${{ secrets.DOCKERHUB_USERNAME }}/librechat-dev-api:latest
docker tag librechat-dev:latest ${{ secrets.DOCKERHUB_USERNAME }}/librechat-dev:${{ github.sha }}
docker push ${{ secrets.DOCKERHUB_USERNAME }}/librechat-dev:${{ github.sha }}
docker tag librechat-dev:latest ${{ secrets.DOCKERHUB_USERNAME }}/librechat-dev:latest
docker push ${{ secrets.DOCKERHUB_USERNAME }}/librechat-dev:latest
76 changes: 62 additions & 14 deletions .github/workflows/latest-images-main.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Docker Compose Build on Main Branch
name: Docker Compose Build Latest Tag (Manual Dispatch)

# The workflow is manually triggered
on:
workflow_dispatch: # This line allows manual triggering
workflow_dispatch:

jobs:
build:
Expand All @@ -12,10 +13,20 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

# Fetch all tags and set the latest tag
- name: Fetch tags and set the latest tag
run: |
git fetch --tags
echo "LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_ENV
# Set up Docker
- name: Set up Docker
uses: docker/setup-buildx-action@v3

# Set up QEMU
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

# Log in to GitHub Container Registry
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
Expand All @@ -24,17 +35,54 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Run docker-compose build
# Prepare Docker Build
- name: Build Docker images
run: |
cp .env.example .env
docker-compose build
docker build -f Dockerfile.multi --target api-build -t librechat-api .
run: cp .env.example .env

# Tag and push the images with the 'latest' tag
- name: Tag image and push
run: |
docker tag librechat:latest ghcr.io/${{ github.repository_owner }}/librechat:latest
docker push ghcr.io/${{ github.repository_owner }}/librechat:latest
docker tag librechat-api:latest ghcr.io/${{ github.repository_owner }}/librechat-api:latest
docker push ghcr.io/${{ github.repository_owner }}/librechat-api:latest
# Docker metadata for librechat-api
- name: Docker metadata for librechat-api
id: meta-librechat-api
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/librechat-api
tags: |
type=raw,value=${{ env.LATEST_TAG }},enable=true
type=raw,value=latest,enable=true
type=semver,pattern={{version}}
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
# Build and push librechat-api
- name: Build and push librechat-api
uses: docker/build-push-action@v5
with:
file: Dockerfile.multi
context: .
push: true
tags: ${{ steps.meta-librechat-api.outputs.tags }}
platforms: linux/amd64,linux/arm64
target: api-build

# Docker metadata for librechat
- name: Docker metadata for librechat
id: meta-librechat
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/librechat
tags: |
type=raw,value=${{ env.LATEST_TAG }},enable=true
type=raw,value=latest,enable=true
type=semver,pattern={{version}}
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
# Build and push librechat
- name: Build and push librechat
uses: docker/build-push-action@v5
with:
file: Dockerfile
context: .
push: true
tags: ${{ steps.meta-librechat.outputs.tags }}
platforms: linux/amd64,linux/arm64
target: node
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,7 @@ auth.json
/packages/ux-shared/
/images

!client/src/components/Nav/SettingsTabs/Data/
!client/src/components/Nav/SettingsTabs/Data/

# User uploads
uploads/
3 changes: 2 additions & 1 deletion api/app/chatgpt-browser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require('dotenv').config();
const { KeyvFile } = require('keyv-file');
const { Constants } = require('librechat-data-provider');
const { getUserKey, checkUserKeyExpiry } = require('../server/services/UserService');

const browserClient = async ({
Expand Down Expand Up @@ -48,7 +49,7 @@ const browserClient = async ({
options = { ...options, parentMessageId, conversationId };
}

if (parentMessageId === '00000000-0000-0000-0000-000000000000') {
if (parentMessageId === Constants.NO_PARENT) {
delete options.conversationId;
}

Expand Down
10 changes: 4 additions & 6 deletions api/app/clients/BaseClient.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const crypto = require('crypto');
const { supportsBalanceCheck } = require('librechat-data-provider');
const { supportsBalanceCheck, Constants } = require('librechat-data-provider');
const { getConvo, getMessages, saveMessage, updateMessage, saveConvo } = require('~/models');
const { addSpaceIfNeeded, isEnabled } = require('~/server/utils');
const checkBalance = require('~/models/checkBalance');
Expand Down Expand Up @@ -77,7 +77,7 @@ class BaseClient {
const saveOptions = this.getSaveOptions();
this.abortController = opts.abortController ?? new AbortController();
const conversationId = opts.conversationId ?? crypto.randomUUID();
const parentMessageId = opts.parentMessageId ?? '00000000-0000-0000-0000-000000000000';
const parentMessageId = opts.parentMessageId ?? Constants.NO_PARENT;
const userMessageId = opts.overrideParentMessageId ?? crypto.randomUUID();
let responseMessageId = opts.responseMessageId ?? crypto.randomUUID();
let head = isEdited ? responseMessageId : parentMessageId;
Expand Down Expand Up @@ -552,7 +552,7 @@ class BaseClient {
*
* Each message object should have an 'id' or 'messageId' property and may have a 'parentMessageId' property.
* The 'parentMessageId' is the ID of the message that the current message is a reply to.
* If 'parentMessageId' is not present, null, or is '00000000-0000-0000-0000-000000000000',
* If 'parentMessageId' is not present, null, or is Constants.NO_PARENT,
* the message is considered a root message.
*
* @param {Object} options - The options for the function.
Expand Down Expand Up @@ -607,9 +607,7 @@ class BaseClient {
}

currentMessageId =
message.parentMessageId === '00000000-0000-0000-0000-000000000000'
? null
: message.parentMessageId;
message.parentMessageId === Constants.NO_PARENT ? null : message.parentMessageId;
}

orderedMessages.reverse();
Expand Down
5 changes: 3 additions & 2 deletions api/app/clients/GoogleClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ const { GoogleVertexAI } = require('langchain/llms/googlevertexai');
const { ChatGoogleGenerativeAI } = require('@langchain/google-genai');
const { ChatGoogleVertexAI } = require('langchain/chat_models/googlevertexai');
const { AIMessage, HumanMessage, SystemMessage } = require('langchain/schema');
const { encodeAndFormat, validateVisionModel } = require('~/server/services/Files/images');
const { encodeAndFormat } = require('~/server/services/Files/images');
const { encoding_for_model: encodingForModel, get_encoding: getEncoding } = require('tiktoken');
const {
validateVisionModel,
getResponseSender,
EModelEndpoint,
endpointSettings,
EModelEndpoint,
AuthKeys,
} = require('librechat-data-provider');
const { getModelMaxTokens } = require('~/utils');
Expand Down
26 changes: 19 additions & 7 deletions api/app/clients/OpenAIClient.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
const OpenAI = require('openai');
const { HttpsProxyAgent } = require('https-proxy-agent');
const { getResponseSender, ImageDetailCost, ImageDetail } = require('librechat-data-provider');
const {
getResponseSender,
validateVisionModel,
ImageDetailCost,
ImageDetail,
} = require('librechat-data-provider');
const { encoding_for_model: encodingForModel, get_encoding: getEncoding } = require('tiktoken');
const {
getModelMaxTokens,
genAzureChatCompletion,
extractBaseURL,
constructAzureURL,
getModelMaxTokens,
genAzureChatCompletion,
} = require('~/utils');
const { encodeAndFormat, validateVisionModel } = require('~/server/services/Files/images');
const { encodeAndFormat } = require('~/server/services/Files/images/encode');
const { truncateText, formatMessage, CUT_OFF_PROMPT } = require('./prompts');
const { handleOpenAIErrors } = require('./tools/util');
const spendTokens = require('~/models/spendTokens');
Expand Down Expand Up @@ -630,6 +635,7 @@ class OpenAIClient extends BaseClient {
context,
tokenBuffer,
initialMessageCount,
conversationId,
}) {
const modelOptions = {
modelName: modelName ?? model,
Expand Down Expand Up @@ -677,7 +683,7 @@ class OpenAIClient extends BaseClient {
callbacks: runManager.createCallbacks({
context,
tokenBuffer,
conversationId: this.conversationId,
conversationId: this.conversationId ?? conversationId,
initialMessageCount,
}),
});
Expand All @@ -693,12 +699,13 @@ class OpenAIClient extends BaseClient {
*
* @param {Object} params - The parameters for the conversation title generation.
* @param {string} params.text - The user's input.
* @param {string} [params.conversationId] - The current conversationId, if not already defined on client initialization.
* @param {string} [params.responseText=''] - The AI's immediate response to the user.
*
* @returns {Promise<string | 'New Chat'>} A promise that resolves to the generated conversation title.
* In case of failure, it will return the default title, "New Chat".
*/
async titleConvo({ text, responseText = '' }) {
async titleConvo({ text, conversationId, responseText = '' }) {
let title = 'New Chat';
const convo = `||>User:
"${truncateText(text)}"
Expand Down Expand Up @@ -758,7 +765,12 @@ ${convo}

try {
this.abortController = new AbortController();
const llm = this.initializeLLM({ ...modelOptions, context: 'title', tokenBuffer: 150 });
const llm = this.initializeLLM({
...modelOptions,
conversationId,
context: 'title',
tokenBuffer: 150,
});
title = await runTitleChain({ llm, text, convo, signal: this.abortController.signal });
} catch (e) {
if (e?.message?.toLowerCase()?.includes('abort')) {
Expand Down
4 changes: 3 additions & 1 deletion api/app/clients/PluginsClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { CallbackManager } = require('langchain/callbacks');
const { BufferMemory, ChatMessageHistory } = require('langchain/memory');
const { initializeCustomAgent, initializeFunctionsAgent } = require('./agents');
const { addImages, buildErrorInput, buildPromptPrefix } = require('./output_parsers');
const { processFileURL } = require('~/server/services/Files/process');
const { EModelEndpoint } = require('librechat-data-provider');
const { formatLangChainMessages } = require('./prompts');
const checkBalance = require('~/models/checkBalance');
Expand Down Expand Up @@ -30,7 +31,7 @@ class PluginsClient extends OpenAIClient {

super.setOptions(options);

if (this.functionsAgent && this.agentOptions.model && !this.useOpenRouter) {
if (this.functionsAgent && this.agentOptions.model && !this.useOpenRouter && !this.azure) {
this.agentOptions.model = this.getFunctionModelName(this.agentOptions.model);
}

Expand Down Expand Up @@ -113,6 +114,7 @@ class PluginsClient extends OpenAIClient {
openAIApiKey: this.openAIApiKey,
conversationId: this.conversationId,
fileStrategy: this.options.req.app.locals.fileStrategy,
processFileURL,
message,
},
});
Expand Down
Loading

0 comments on commit e16e238

Please sign in to comment.