mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-19 16:56:12 +01:00
feat: claude integration (#552)
* feat: bare bones implementation of claude client (WIP) * feat: client implementation of Claude (WIP) * fix: add claude to store * feat: bare bones implementation of claude client (WIP) * switch eventsource * Try new method of calling claude with anthropic sdk * (WIP) Finish initial claude client implementation and api * debugging update * fix(ClaudeClient.js): fix prompt prefixes for HUMAN_PROMPT and AI_PROMPT fix(ClaudeClient.js): refactor buildMessages logic for correct handling of messages refactor(ClaudeClient.js): refactor buildPrompt method to buildMessages for use in BaseClient sendMessage method refactor(ClaudeClient.js): refactor getCompletion method to sendCompletion for use in BaseClient sendMessage method refactor(ClaudeClient.js): omit getMessageMapMethod method for future refactoring refactor(ClaudeClient.js): remove unused sendMessage method to prefer BaseClient message fix(askClaude.js): error in getIds method was causing a frontend crash, userMessage was not defined fix(askClaude.js): import abortMessage function from utils module feat(askClaude.js): add /abort route to handle message abort requests feat(askClaude.js): create abortControllers map to store abort controllers feat(askClaude.js): implement abortAsk function to handle message abort logic feat(askClaude.js): add onStart callback to handle message start logic feat(HoverButtons.jsx): add 'claude' as a supported endpoint for branching * fix(ClaudeClient.js): update defaultPrefix and promptPrefix messages includes 'Remember your instructions' as Claude is trained to recognize labels preceding colons as participants of a conversation * Change name from claude to anthropic * add settings to handleSubmit and models to endpoints * Implement Claude settings * use svg for anthropic icon * Implement abort * Implement reverse proxy * remove png icons * replace web browser plugin * remove default prefix * fix styling of claude icon * fix console error from svg properties * remove single quote requirement from eslintrc * fix(AnthropicClient.js): fix labels for HUMAN_PROMPT and AI_PROMPT feat(AnthropicClient.js): add support for custom userLabel and modelLabel options feat(AnthropicClient.js): add user_id metadata to requestOptions in getCompletion method feat(anthropic, AnthropicClient.js): add debug logging * refactor(AnthropicClient.js): change promptSuffix variable declaration from let to const * fix(EndpointOptionsDialog.jsx): remove unnecessary code that changes endpointName from 'anthropic' to 'Claude' fix(utils/index.jsx): fix alternateName value for 'anthropic' from 'Claude' to 'Anthropic' * fix(AnthropicIcon): fix sizing/rendering/name of anthropic icon * fix(AnthropicClient.js): change maxContextTokens default value to 99999 fix(AnthropicClient.js): change maxResponseTokens default value to 1500 fix(AnthropicClient.js): remove unnecessary code for setting maxContextTokens and maxResponseTokens based on modelOptions fix(AnthropicClient.js): change max_tokens_to_sample default value to 1500 fix(anthropic.js): pass endpointOption.token to AnthropicClient constructor * Update .env.example * fix(AnthropicClient.js): remove exceeding message when it puts us over the token limit fix(AnthropicClient.js): handle case when the first message exceeds the token limit fix(AnthropicClient.js): throw error when prompt is too long fix(AnthropicClient.js): adjust max tokens calculation to use maxOutputTokens fix(anthropic.js): remove console.log statement in ask route * feat(server/index): increase incoming json payload allowed size --------- Co-authored-by: Danny Avila <messagedaniel@protonmail.com>
This commit is contained in:
parent
981d009508
commit
9e931229e2
36 changed files with 1455 additions and 30 deletions
107
client/src/components/Input/AnthropicOptions/index.jsx
Normal file
107
client/src/components/Input/AnthropicOptions/index.jsx
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import { useState } from 'react';
|
||||
import { Settings2 } from 'lucide-react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { SelectDropDown, Button } from '~/components';
|
||||
import EndpointOptionsPopover from '../../Endpoints/EndpointOptionsPopover';
|
||||
import SaveAsPresetDialog from '../../Endpoints/SaveAsPresetDialog';
|
||||
import Settings from '../../Endpoints/Anthropic/Settings.jsx';
|
||||
import { cn } from '~/utils/';
|
||||
|
||||
import store from '~/store';
|
||||
|
||||
function AnthropicOptions() {
|
||||
const [advancedMode, setAdvancedMode] = useState(false);
|
||||
const [saveAsDialogShow, setSaveAsDialogShow] = useState(false);
|
||||
|
||||
const [conversation, setConversation] = useRecoilState(store.conversation) || {};
|
||||
const { endpoint, conversationId } = conversation;
|
||||
const { model, modelLabel, promptPrefix, temperature, topP, topK, maxOutputTokens } =
|
||||
conversation;
|
||||
const endpointsConfig = useRecoilValue(store.endpointsConfig);
|
||||
|
||||
if (endpoint !== 'anthropic') return null;
|
||||
if (conversationId !== 'new') return null;
|
||||
|
||||
const models = endpointsConfig?.['anthropic']?.['availableModels'] || [];
|
||||
|
||||
const triggerAdvancedMode = () => setAdvancedMode((prev) => !prev);
|
||||
|
||||
const switchToSimpleMode = () => {
|
||||
setAdvancedMode(false);
|
||||
};
|
||||
|
||||
const saveAsPreset = () => {
|
||||
setSaveAsDialogShow(true);
|
||||
};
|
||||
|
||||
const setOption = (param) => (newValue) => {
|
||||
let update = {};
|
||||
update[param] = newValue;
|
||||
setConversation((prevState) => ({
|
||||
...prevState,
|
||||
...update
|
||||
}));
|
||||
};
|
||||
|
||||
const cardStyle =
|
||||
'transition-colors shadow-md rounded-md min-w-[75px] font-normal bg-white border-black/10 hover:border-black/10 focus:border-black/10 dark:border-black/10 dark:hover:border-black/10 dark:focus:border-black/10 border dark:bg-gray-700 text-black dark:text-white';
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={
|
||||
'openAIOptions-simple-container flex w-full flex-wrap items-center justify-center gap-2' +
|
||||
(!advancedMode ? ' show' : '')
|
||||
}
|
||||
>
|
||||
<SelectDropDown
|
||||
value={model}
|
||||
setValue={setOption('model')}
|
||||
availableValues={models}
|
||||
showAbove={true}
|
||||
showLabel={false}
|
||||
className={cn(
|
||||
cardStyle,
|
||||
'min-w-48 z-50 flex h-[40px] w-48 flex-none items-center justify-center px-4 ring-0 hover:cursor-pointer hover:bg-slate-50 focus:ring-0 focus:ring-offset-0 data-[state=open]:bg-slate-50 dark:bg-gray-700 dark:hover:bg-gray-600 dark:data-[state=open]:bg-gray-600'
|
||||
)}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
className={cn(
|
||||
cardStyle,
|
||||
'min-w-4 z-50 flex h-[40px] flex-none items-center justify-center px-4 hover:bg-slate-50 focus:ring-0 focus:ring-offset-0 dark:hover:bg-gray-600'
|
||||
)}
|
||||
onClick={triggerAdvancedMode}
|
||||
>
|
||||
<Settings2 className="w-4 text-gray-600 dark:text-white" />
|
||||
</Button>
|
||||
</div>
|
||||
<EndpointOptionsPopover
|
||||
content={
|
||||
<div className="px-4 py-4">
|
||||
<Settings
|
||||
model={model}
|
||||
modelLabel={modelLabel}
|
||||
promptPrefix={promptPrefix}
|
||||
temperature={temperature}
|
||||
topP={topP}
|
||||
topK={topK}
|
||||
maxOutputTokens={maxOutputTokens}
|
||||
setOption={setOption}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
visible={advancedMode}
|
||||
saveAsPreset={saveAsPreset}
|
||||
switchToSimpleMode={switchToSimpleMode}
|
||||
/>
|
||||
<SaveAsPresetDialog
|
||||
open={saveAsDialogShow}
|
||||
onOpenChange={setSaveAsDialogShow}
|
||||
preset={conversation}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default AnthropicOptions;
|
||||
|
|
@ -6,6 +6,7 @@ import PluginsOptions from './PluginsOptions';
|
|||
import ChatGPTOptions from './ChatGPTOptions';
|
||||
import BingAIOptions from './BingAIOptions';
|
||||
import GoogleOptions from './GoogleOptions';
|
||||
import AnthropicOptions from './AnthropicOptions';
|
||||
import NewConversationMenu from './NewConversationMenu';
|
||||
import AdjustToneButton from './AdjustToneButton';
|
||||
import Footer from './Footer';
|
||||
|
|
@ -130,6 +131,7 @@ export default function TextChat({ isSearchView = false }) {
|
|||
<ChatGPTOptions />
|
||||
<GoogleOptions />
|
||||
<BingAIOptions show={showBingToneSetting} />
|
||||
<AnthropicOptions />
|
||||
</span>
|
||||
</div>
|
||||
<div className="input-panel md:bg-vert-light-gradient dark:md:bg-vert-dark-gradient relative w-full border-t bg-white py-2 dark:border-white/20 dark:bg-gray-800 md:border-t-0 md:border-transparent md:bg-transparent md:dark:border-transparent md:dark:bg-transparent">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue