mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 01:40:15 +01:00
Merge pull request #74 from wtlyu/feat-model-based-on-key
feat: show model based on configured Keys
This commit is contained in:
commit
5cac7e48f0
6 changed files with 63 additions and 12 deletions
|
|
@ -51,6 +51,14 @@ app.use('/api/prompts', routes.authenticatedOr401, routes.prompts);
|
||||||
app.use('/auth', routes.auth);
|
app.use('/auth', routes.auth);
|
||||||
|
|
||||||
|
|
||||||
|
app.get('/api/models', function (req, res) {
|
||||||
|
const hasOpenAI = !!process.env.OPENAI_KEY;
|
||||||
|
const hasChatGpt = !!process.env.CHATGPT_TOKEN;
|
||||||
|
const hasBing = !!process.env.BING_TOKEN;
|
||||||
|
|
||||||
|
res.send(JSON.stringify({ hasOpenAI, hasChatGpt, hasBing }));
|
||||||
|
});
|
||||||
|
|
||||||
app.listen(port, host, () => {
|
app.listen(port, host, () => {
|
||||||
if (host=='0.0.0.0')
|
if (host=='0.0.0.0')
|
||||||
console.log(`Server listening on all interface at port ${port}. Use http://localhost:${port} to access it`);
|
console.log(`Server listening on all interface at port ${port}. Use http://localhost:${port} to access it`);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import MobileNav from './components/Nav/MobileNav';
|
||||||
import useDocumentTitle from '~/hooks/useDocumentTitle';
|
import useDocumentTitle from '~/hooks/useDocumentTitle';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import { setUser } from './store/userReducer';
|
import { setUser } from './store/userReducer';
|
||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ export default function ModelItem({ modelName, value, model, onSelect, id, chatG
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initial[value]) {
|
if (initial[value])
|
||||||
return (
|
return (
|
||||||
<DropdownMenuRadioItem
|
<DropdownMenuRadioItem
|
||||||
value={value}
|
value={value}
|
||||||
|
|
@ -56,7 +56,7 @@ export default function ModelItem({ modelName, value, model, onSelect, id, chatG
|
||||||
{value === 'chatgpt' && <sup>$</sup>}
|
{value === 'chatgpt' && <sup>$</sup>}
|
||||||
</DropdownMenuRadioItem>
|
</DropdownMenuRadioItem>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
const handleMouseOver = () => {
|
const handleMouseOver = () => {
|
||||||
setIsHovering(true);
|
setIsHovering(true);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
setSubmission,
|
setSubmission,
|
||||||
|
|
@ -11,7 +12,7 @@ import { setNewConvo } from '~/store/convoSlice';
|
||||||
import ModelDialog from './ModelDialog';
|
import ModelDialog from './ModelDialog';
|
||||||
import MenuItems from './MenuItems';
|
import MenuItems from './MenuItems';
|
||||||
import { swr } from '~/utils/fetchers';
|
import { swr } from '~/utils/fetchers';
|
||||||
import { setModels } from '~/store/modelSlice';
|
import { setModels, setInitial } from '~/store/modelSlice';
|
||||||
import { setMessages } from '~/store/messageSlice';
|
import { setMessages } from '~/store/messageSlice';
|
||||||
import { setText } from '~/store/textSlice';
|
import { setText } from '~/store/textSlice';
|
||||||
import GPTIcon from '../svg/GPTIcon';
|
import GPTIcon from '../svg/GPTIcon';
|
||||||
|
|
@ -62,10 +63,47 @@ export default function ModelMenu() {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
axios.get('/api/models', {
|
||||||
|
timeout: 1000,
|
||||||
|
withCredentials: true
|
||||||
|
}).then((res) => {
|
||||||
|
return res.data
|
||||||
|
}).then((data) => {
|
||||||
|
const initial = {chatgpt: data?.hasOpenAI, chatgptCustom: data?.hasOpenAI, bingai: data?.hasBing, sydney: data?.hasBing, chatgptBrowser: data?.hasChatGpt}
|
||||||
|
dispatch(setInitial(initial))
|
||||||
|
// TODO, auto reset default model
|
||||||
|
if (data?.hasOpenAI) {
|
||||||
|
dispatch(setModel('chatgpt'));
|
||||||
|
dispatch(setDisabled(false));
|
||||||
|
dispatch(setCustomModel(null));
|
||||||
|
dispatch(setCustomGpt({ chatGptLabel: null, promptPrefix: null }));
|
||||||
|
} else if (data?.hasBing) {
|
||||||
|
dispatch(setModel('bingai'));
|
||||||
|
dispatch(setDisabled(false));
|
||||||
|
dispatch(setCustomModel(null));
|
||||||
|
dispatch(setCustomGpt({ chatGptLabel: null, promptPrefix: null }));
|
||||||
|
} else if (data?.hasChatGpt) {
|
||||||
|
dispatch(setModel('chatgptBrowser'));
|
||||||
|
dispatch(setDisabled(false));
|
||||||
|
dispatch(setCustomModel(null));
|
||||||
|
dispatch(setCustomGpt({ chatGptLabel: null, promptPrefix: null }));
|
||||||
|
} else {
|
||||||
|
dispatch(setDisabled(true));
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error(error)
|
||||||
|
console.log('Not login!')
|
||||||
|
window.location.href = "/auth/login";
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
localStorage.setItem('model', JSON.stringify(model));
|
localStorage.setItem('model', JSON.stringify(model));
|
||||||
}, [model]);
|
}, [model]);
|
||||||
|
|
||||||
|
const filteredModels = models.filter(({model}) => initial[model])
|
||||||
|
|
||||||
const onChange = (value) => {
|
const onChange = (value) => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -166,10 +204,12 @@ export default function ModelMenu() {
|
||||||
onValueChange={onChange}
|
onValueChange={onChange}
|
||||||
className="overflow-y-auto"
|
className="overflow-y-auto"
|
||||||
>
|
>
|
||||||
|
{filteredModels.length?
|
||||||
<MenuItems
|
<MenuItems
|
||||||
models={models}
|
models={filteredModels}
|
||||||
onSelect={onChange}
|
onSelect={onChange}
|
||||||
/>
|
/>:<DropdownMenuLabel className="dark:text-gray-300">No model available.</DropdownMenuLabel>
|
||||||
|
}
|
||||||
</DropdownMenuRadioGroup>
|
</DropdownMenuRadioGroup>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const initialState = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
modelMap: {},
|
modelMap: {},
|
||||||
initial: { chatgpt: true, chatgptCustom: true, bingai: true, sydney: true, chatgptBrowser: true }
|
initial: { chatgpt: false, chatgptCustom: false, bingai: false, sydney: false, chatgptBrowser: false }
|
||||||
// initial: { chatgpt: true, chatgptCustom: true, bingai: true, }
|
// initial: { chatgpt: true, chatgptCustom: true, bingai: true, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -56,10 +56,13 @@ const currentSlice = createSlice({
|
||||||
});
|
});
|
||||||
|
|
||||||
state.modelMap = modelMap;
|
state.modelMap = modelMap;
|
||||||
|
},
|
||||||
|
setInitial: (state, action) => {
|
||||||
|
state.initial = action.payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { setModels } = currentSlice.actions;
|
export const { setModels, setInitial } = currentSlice.actions;
|
||||||
|
|
||||||
export default currentSlice.reducer;
|
export default currentSlice.reducer;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ const initialState = {
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
submission: {},
|
submission: {},
|
||||||
stopStream: false,
|
stopStream: false,
|
||||||
disabled: false,
|
disabled: true,
|
||||||
model: 'chatgpt',
|
model: 'chatgpt',
|
||||||
promptPrefix: null,
|
promptPrefix: null,
|
||||||
chatGptLabel: null,
|
chatGptLabel: null,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue