Skip to content

Commit

Permalink
Feature: Anthropic 설정을 언어 모델 기능 설정에 추가 (#1)
Browse files Browse the repository at this point in the history
* chore: update dependencies in package.json

* feat(constants.ts): update ANTHROPIC_MODELS with new model versions and remove deprecated ones

* feat(settings): add Anthropic settings component for configuring Anthropic API integration

* feat(chatbot-header.tsx): add fallback to ANTHROPIC_MODELS if no models are provided for ANTHROPIC provider
chore(constants.ts): import ANTHROPIC_MODELS to be used in chatbot-header component

* chore(package.json): update devDependencies and dependencies to latest versions for improved stability and features

* chore(package.json): remove unused openai dependency to clean up project dependencies

* style(chatbot-header.tsx): reorder imports for better readability
style(chatbot-header.tsx): fix spacing and formatting issues for consistency

* feat(createChatModelInstance.ts): add support for ChatAnthropic model to enhance AI model options

* fix(language-models): comment out AnthropicSetting due to CORS error

* feat(chatbot-header): update model filtering logic to exclude 'embed' model

* refactor(chatbot-header): optimize model filtering logic and improve code readability

* fix(anthropic-setting): set default value for allowStream to false

* refactor(language-models): remove commented out AnthropicSetting component and add TODO comment for CORS error

* refactor(setting): remove unused ANTHROPIC_MODELS import

* refactor(setting): optimize AnthropicSetting component and improve code readability
  • Loading branch information
anpigon authored Jul 19, 2024
1 parent af5c5bc commit 13cd44f
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 94 deletions.
Binary file modified bun.lockb
Binary file not shown.
180 changes: 90 additions & 90 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,92 +1,92 @@
{
"name": "max-chatbot",
"version": "0.8.2",
"description": "Generate and brainstorm ideas while creating your notes using Large Language Models (LLMs) from Ollama, LM Studio, Anthropic, OpenAI, Mistral AI, and more for Obsidian.",
"main": "main.js",
"scripts": {
"dev": "VITE_CJS_IGNORE_WARNING=true vite build --mode development --watch",
"build": "VITE_CJS_IGNORE_WARNING=true vite build --mode production",
"version": "node version-bump.mjs && git add manifest.json versions.json",
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
"prepare": "husky",
"lint": "eslint ./src",
"lint:fix": "eslint ./src --fix",
"lint:quiet": "eslint ./src --quiet",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"obsidian",
"chatbot",
"chatgpt",
"ollama"
],
"author": "anpigon",
"license": "MIT",
"devDependencies": {
"@commitlint/config-conventional": "^19.2.2",
"@eslint/js": "^9.5.0",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-typescript": "^11.1.6",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/lodash": "^4.17.5",
"@types/node": "^20.14.7",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.10.0",
"@vitejs/plugin-react": "^4.3.1",
"@vitejs/plugin-react-swc": "^3.7.0",
"autoprefixer": "^10.4.19",
"builtin-modules": "^3.3.0",
"bun-types": "latest",
"esbuild": "0.21.5",
"eslint": "^9.5.0",
"husky": "^9.0.11",
"obsidian": "latest",
"postcss": "^8.4.38",
"postcss-prefix-selector": "^1.16.1",
"prettier": "^3.3.2",
"prettier-plugin-sort-imports": "^1.8.5",
"prettier-plugin-tailwindcss": "^0.6.5",
"rollup-plugin-copy": "^3.5.0",
"tailwindcss": "^3.4.4",
"tslib": "^2.6.3",
"typescript": "^5.4.5",
"typescript-eslint": "^7.13.1",
"vite": "^5.3.1"
},
"dependencies": {
"@commitlint/cli": "^19.3.0",
"@heroicons/react": "^2.1.4",
"@langchain/community": "^0.2.12",
"@langchain/google-genai": "^0.0.20",
"@langchain/groq": "^0.0.12",
"@langchain/openai": "^0.1.3",
"@msgpack/msgpack": "^3.0.0-beta2",
"@orama/orama": "^2.0.20",
"@popperjs/core": "^2.11.8",
"clsx": "^2.1.1",
"i18next": "^23.11.5",
"langchain": "^0.2.5",
"lodash": "^4.17.21",
"merge-refs": "^1.3.0",
"monkey-around": "^2.3.0",
"openai": "^4.52.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^14.1.2",
"tailwind-merge": "^2.3.0",
"usehooks-ts": "^3.1.0"
},
"overrides": {
"@langchain/core": "0.2.0"
},
"resolutions": {
"@langchain/core": "0.2.0"
},
"pnpm": {
"overrides": {
"@langchain/core": "0.2.0"
}
}
"name": "max-chatbot",
"version": "0.8.2",
"description": "Generate and brainstorm ideas while creating your notes using Large Language Models (LLMs) from Ollama, LM Studio, Anthropic, OpenAI, Mistral AI, and more for Obsidian.",
"main": "main.js",
"scripts": {
"dev": "VITE_CJS_IGNORE_WARNING=true vite build --mode development --watch",
"build": "VITE_CJS_IGNORE_WARNING=true vite build --mode production",
"version": "node version-bump.mjs && git add manifest.json versions.json",
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
"prepare": "husky",
"lint": "eslint ./src",
"lint:fix": "eslint ./src --fix",
"lint:quiet": "eslint ./src --quiet",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"obsidian",
"chatbot",
"chatgpt",
"ollama"
],
"author": "anpigon",
"license": "MIT",
"devDependencies": {
"@commitlint/config-conventional": "^19.2.2",
"@eslint/js": "^9.6.0",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-typescript": "^11.1.6",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/lodash": "^4.17.6",
"@types/node": "^20.14.10",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/parser": "^7.15.0",
"@vitejs/plugin-react": "^4.3.1",
"@vitejs/plugin-react-swc": "^3.7.0",
"autoprefixer": "^10.4.19",
"builtin-modules": "^3.3.0",
"bun-types": "latest",
"esbuild": "0.23.0",
"eslint": "^9.6.0",
"husky": "^9.0.11",
"obsidian": "latest",
"postcss": "^8.4.39",
"postcss-prefix-selector": "^1.16.1",
"prettier": "^3.3.2",
"prettier-plugin-sort-imports": "^1.8.5",
"prettier-plugin-tailwindcss": "^0.6.5",
"rollup-plugin-copy": "^3.5.0",
"tailwindcss": "^3.4.4",
"tslib": "^2.6.3",
"typescript": "^5.4.5",
"typescript-eslint": "^7.15.0",
"vite": "^5.3.3"
},
"dependencies": {
"@commitlint/cli": "^19.3.0",
"@heroicons/react": "^2.1.4",
"@langchain/anthropic": "^0.2.3",
"@langchain/community": "^0.2.17",
"@langchain/google-genai": "^0.0.21",
"@langchain/groq": "^0.0.13",
"@langchain/openai": "^0.2.1",
"@msgpack/msgpack": "3.0.0-beta2",
"@orama/orama": "^2.0.21",
"@popperjs/core": "^2.11.8",
"clsx": "^2.1.1",
"i18next": "^23.11.5",
"langchain": "^0.2.8",
"lodash": "^4.17.21",
"merge-refs": "^1.3.0",
"monkey-around": "^2.3.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^14.1.2",
"tailwind-merge": "^2.3.0",
"usehooks-ts": "^3.1.0"
},
"overrides": {
"@langchain/core": "0.2.14"
},
"resolutions": {
"@langchain/core": "0.2.14"
},
"pnpm": {
"overrides": {
"@langchain/core": "0.2.14"
}
}
}
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const UPSTAGE_MODELS = [
'solar-1-mini-chat', // GPT-3.5보다 뛰어난 성능을 제공하는 소형 LLM으로, 영어와 한국어를 모두 지원하는 강력한 다국어 기능을 갖추고 있어 더 작은 패키지로 높은 효율성을 제공합니다. Context Length: 32768
'solar-1-mini-chat-ja', // 영어와 한국어의 높은 효율성과 성능을 유지하면서 일본어에 특화된 solar-mini-chat의 기능을 확장한 소형 LLM입니다. Context Length: 32768
];
export const ANTHROPIC_MODELS = ['claude-instant-1.2', 'claude-2.0', 'claude-2.1', 'claude-3-opus-20240229', 'claude-3-sonnet-20240229'];
export const ANTHROPIC_MODELS = ['claude-3-5-sonnet-20240620', 'claude-3-opus-20240229', 'claude-3-sonnet-20240229', 'claude-3-haiku-20240307'];
export const OPEN_AI_MODELS = ['gpt-3.5-turbo', 'gpt-4o', 'gpt-4'];

export const enum LLM_PROVIDERS {
Expand Down
15 changes: 12 additions & 3 deletions src/features/chatbot/components/chatbot-header.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {ReactNode, type ChangeEventHandler, type FC, type PropsWithChildren} from 'react';

import {ANTHROPIC_MODELS, LLM_PROVIDERS} from '@/constants';
import {ProviderModels} from '@/hooks/useEnabledModels';
import {Dropdown} from '@/components/form/dropdown';
import {LLM_PROVIDERS} from '@/constants';

interface ChatbotHeaderProps extends PropsWithChildren {
botName: string;
Expand All @@ -18,6 +18,14 @@ interface ChatbotHeaderProps extends PropsWithChildren {
rightComponent?: ReactNode;
}

function getModels(provider: LLM_PROVIDERS, models: string[]) {
let currentModels = models.filter(model => model !== 'embed');
if (provider === LLM_PROVIDERS.ANTHROPIC && !currentModels?.length) {
currentModels = ANTHROPIC_MODELS;
}
return currentModels;
}

export const ChatbotHeader: FC<ChatbotHeaderProps> = ({botName, providers, disabled, currentModel, onChangeModel, leftComponent, rightComponent, children}) => {
const handleChangeModel: ChangeEventHandler<HTMLSelectElement> = e => {
const value = e.target.value;
Expand All @@ -37,11 +45,12 @@ export const ChatbotHeader: FC<ChatbotHeaderProps> = ({botName, providers, disab
disabled={disabled}
>
{providers
?.filter(({provider, models}) => models.length > 0)
?.filter(({models}) => models.length > 0)
.map(({provider, models}) => {
const currentModels = getModels(provider, models);
return (
<optgroup key={provider} label={provider}>
{models.map(model => {
{currentModels.map(model => {
const value = `${provider}/${model}`;
return (
<option key={value} value={value}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {useCallback, useState, useEffect} from 'react';
import {useTranslation} from 'react-i18next';
import {twMerge} from 'tailwind-merge';
import clsx from 'clsx';

import {SettingItem} from '@/components/settings/setting-item';
import {usePlugin, useSettings} from '@/hooks/useApp';
import {useSettingDispatch} from '../../context';
import {Toggle} from '@/components/form/toggle';

export const AnthropicSetting = () => {
const {t} = useTranslation('settings');

const plugin = usePlugin();
const settings = useSettings();
const {refreshChatbotView} = useSettingDispatch();
const providerSettings = settings.providers.ANTHROPIC;

const [enable, setEnable] = useState(providerSettings?.enable ?? false);
const [apiKey, setApiKey] = useState(providerSettings?.apiKey ?? '');
const [allowStream, setAllowStream] = useState(providerSettings?.allowStream ?? false);

useEffect(() => {
const save = async () => {
await plugin.saveSettings();
refreshChatbotView();
};
void save();
}, [enable, apiKey, allowStream, plugin]);

return (
<>
<SettingItem heading name={t('Anthropic')} className="bg-secondary rounded-lg !px-3 mt-1">
<Toggle
checked={enable}
onChange={event => {
const value = event.target.checked;
setEnable(value);
providerSettings.enable = value;
}}
/>
</SettingItem>

<div className={twMerge(clsx('p-3 hidden', {block: enable}))}>
<SettingItem name={t('Provider API Key', {name: 'Anthropic API'})} description={t('Insert your provider API Key', {name: 'Anthropic API'})}>
<input
type="password"
spellCheck={false}
placeholder="sk-ant-api03-...-57SQAA"
defaultValue={apiKey}
onChange={event => {
const value = event.target.value?.trim();
setApiKey(value);
providerSettings.apiKey = value;
}}
/>
</SettingItem>

<SettingItem name={t('Allow Stream')} description={t('Allow the model to stream responses.', {name: 'Anthropic'})}>
<Toggle
name="allowStream"
checked={allowStream}
onChange={event => {
const value = event.target.checked;
setAllowStream(value);
providerSettings.allowStream = value;
}}
/>
</SettingItem>
</div>
</>
);
};
2 changes: 2 additions & 0 deletions src/features/setting/components/language-models/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export default function LanguageModels() {
<GoogleSetting />
<GroqSetting />
<UpstageSetting />
{/* TODO: Anthropic API의 CORS 에러로 인해 현재는 주석 처리 됨. 이후 CORS 문제 해결 시 주석 해제 요망 */}
{/* <AnthropicSetting /> */}
</>
);
}
3 changes: 3 additions & 0 deletions src/libs/ai/createChatModelInstance.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {ChatOllama} from '@langchain/community/chat_models/ollama';
import {ChatGoogleGenerativeAI} from '@langchain/google-genai';
import {ChatAnthropic} from '@langchain/anthropic';
import {ChatOpenAI} from '@langchain/openai';
import {ChatGroq} from '@langchain/groq';

Expand All @@ -20,6 +21,8 @@ export default function createChatModelInstance(provider: LLM_PROVIDERS, model:
return new ChatGoogleGenerativeAI(options);
case LLM_PROVIDERS.GROQ:
return new ChatGroq(options);
case LLM_PROVIDERS.ANTHROPIC:
return new ChatAnthropic(options);
default:
return new ChatOpenAI({
...options,
Expand Down

0 comments on commit 13cd44f

Please sign in to comment.