diff --git a/.github/workflows/aws-preview.yml b/.github/workflows/aws-preview.yml index 8ce98a7f..fcd59487 100644 --- a/.github/workflows/aws-preview.yml +++ b/.github/workflows/aws-preview.yml @@ -21,7 +21,7 @@ env: permissions: id-token: write # This is required for requesting the JWT contents: read # This is required for actions/checkout - actions: write + actions: write jobs: deploy: @@ -67,6 +67,7 @@ jobs: ParameterKey=OpenAIAPIKey,ParameterValue=${{ secrets.OPENAI_API_KEY }} \ ParameterKey=OpenAIBaseUrl,ParameterValue=${{ vars.OPENAI_BASE_URL || 'https://api.openai.com/v1' }} \ ParameterKey=GeminiAPIKey,ParameterValue=${{ secrets.GEMINI_API_KEY }} \ + ParameterKey=DeepSeekAPIKey,ParameterValue=${{ secrets.DEEPSEEK_API_KEY }} \ ParameterKey=SupabaseServiceKey,ParameterValue=${{ secrets.SUPABASE_SERVICE_KEY }} \ ParameterKey=SupabaseUrl,ParameterValue=${{ secrets.SUPABASE_URL }} \ ParameterKey=TavilyAPIKey,ParameterValue=${{ secrets.TAVILY_API_KEY }} \ diff --git a/.github/workflows/aws-prod.yml b/.github/workflows/aws-prod.yml index 8e272488..b72deea4 100644 --- a/.github/workflows/aws-prod.yml +++ b/.github/workflows/aws-prod.yml @@ -59,6 +59,7 @@ jobs: ParameterKey=GithubAppsClientId,ParameterValue=${{ secrets.X_GITHUB_APPS_CLIENT_ID }} \ ParameterKey=GithubAppsClientSecret,ParameterValue=${{ secrets.X_GITHUB_APPS_CLIENT_SECRET }} \ ParameterKey=OpenAIAPIKey,ParameterValue=${{ secrets.OPENAI_API_KEY }} \ + ParameterKey=DeepSeekAPIKey,ParameterValue=${{ secrets.DEEPSEEK_API_KEY }} \ ParameterKey=OpenAIBaseUrl,ParameterValue=${{ vars.OPENAI_BASE_URL || 'https://api.openai.com/v1' }} \ ParameterKey=GeminiAPIKey,ParameterValue=${{ secrets.GEMINI_API_KEY }} \ ParameterKey=SupabaseServiceKey,ParameterValue=${{ secrets.SUPABASE_SERVICE_KEY }} \ diff --git a/client/.kiwi/en/components.ts b/client/.kiwi/en/components.ts index e309da8a..5e757c95 100644 --- a/client/.kiwi/en/components.ts +++ b/client/.kiwi/en/components.ts @@ -59,7 +59,7 @@ export default { gITHU: ' GitHub platform', }, CreateButton: { - chuangJianTOK: 'Create Token', + chuangJianTOK: 'Custodial Token', }, CreateModal: { miYao: 'Secret Key', diff --git a/client/.kiwi/ja/components.ts b/client/.kiwi/ja/components.ts index 240f4380..f1210268 100644 --- a/client/.kiwi/ja/components.ts +++ b/client/.kiwi/ja/components.ts @@ -58,7 +58,7 @@ export default { gITHU: ' GitHubプラットフォーム', }, CreateButton: { - chuangJianTOK: 'トークンを作成', + chuangJianTOK: '托管されたトークン', }, CreateModal: { miYao: 'シークレットキー', diff --git a/client/.kiwi/ko/components.ts b/client/.kiwi/ko/components.ts index 46c0b89e..ef23e3cc 100644 --- a/client/.kiwi/ko/components.ts +++ b/client/.kiwi/ko/components.ts @@ -58,7 +58,7 @@ export default { gITHU: ' GitHub 플랫폼', }, CreateButton: { - chuangJianTOK: '토큰 생성', + chuangJianTOK: '위탁된 토큰', }, CreateModal: { miYao: '비밀 키', diff --git a/client/.kiwi/zh-CN/components.ts b/client/.kiwi/zh-CN/components.ts index 9966dd1c..11abc14f 100644 --- a/client/.kiwi/zh-CN/components.ts +++ b/client/.kiwi/zh-CN/components.ts @@ -58,7 +58,7 @@ export default { gITHU: ' GitHub 平台', }, CreateButton: { - chuangJianTOK: '创建 Token', + chuangJianTOK: '托管 Token', }, CreateModal: { miYao: '密钥', diff --git a/client/.kiwi/zh-TW/components.ts b/client/.kiwi/zh-TW/components.ts index 530ee1d7..5117a32f 100644 --- a/client/.kiwi/zh-TW/components.ts +++ b/client/.kiwi/zh-TW/components.ts @@ -58,7 +58,7 @@ export default { gITHU: ' GitHub 平台', }, CreateButton: { - chuangJianTOK: '創建 Token', + chuangJianTOK: '代管 Token', }, CreateModal: { miYao: '密鑰', diff --git a/client/app/hooks/useToken.ts b/client/app/hooks/useToken.ts index cc12de36..96fe3966 100644 --- a/client/app/hooks/useToken.ts +++ b/client/app/hooks/useToken.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { getTokenList } from '../services/TokensController'; +import { getTokenList, getLLMList } from '../services/TokensController'; import { Tables, Database } from '@/types/database.types'; import { Updater, useImmer } from 'use-immer'; @@ -21,3 +21,11 @@ export function useCreateToken(): [LLMTokenInsert, Updater] { return [llmToken, setLLMToken] } + +export function useListLLMs() { + return useQuery({ + queryKey: [`llm.list`], + queryFn: async () => getLLMList(), + retry: false, + }); +} \ No newline at end of file diff --git a/client/app/services/TokensController.ts b/client/app/services/TokensController.ts index 363a4f41..b7b54b03 100644 --- a/client/app/services/TokensController.ts +++ b/client/app/services/TokensController.ts @@ -9,6 +9,12 @@ export async function getTokenList() { return response.data.data; } +export async function getLLMList() { + const response = await axios.get(`${apiDomain}/api/user/llms`); + return response.data; +} + + export async function deleteToken(id: string) { const response = await axios.delete(`${apiDomain}/api/user/llm_token/${id}`); return response.data; @@ -34,3 +40,4 @@ export async function analyzeTopUsers() { return response.data; } + diff --git a/client/app/user/tokens/components/CreateModal.tsx b/client/app/user/tokens/components/CreateModal.tsx index caf932d7..9ad28b5e 100644 --- a/client/app/user/tokens/components/CreateModal.tsx +++ b/client/app/user/tokens/components/CreateModal.tsx @@ -1,5 +1,5 @@ import I18N from '@/app/utils/I18N'; -import { LLMTokenInsert, useCreateToken } from '@/app/hooks/useToken'; +import { LLMTokenInsert, useCreateToken, useListLLMs } from '@/app/hooks/useToken'; import { Button, Input, @@ -24,6 +24,8 @@ export interface CreateModalProps { export default function CreateModal({ isOpen, onClose, isLoading, onCreate }: CreateModalProps) { const [llmToken, setLLMToken] = useCreateToken(); + const { data: llms = [] } = useListLLMs(); + useEffect(() => setLLMToken({}), []); const handleChange = (e: React.ChangeEvent) => { @@ -48,7 +50,7 @@ export default function CreateModal({ isOpen, onClose, isLoading, onCreate }: Cr
- +
- openai - gemini + {llms?.map(llm => {llm})}
diff --git a/server/agent/llm/clients/deepseek.py b/server/agent/llm/clients/deepseek.py new file mode 100644 index 00000000..4403f263 --- /dev/null +++ b/server/agent/llm/clients/deepseek.py @@ -0,0 +1,49 @@ + + +from typing import Any, List, Optional +from langchain_openai import ChatOpenAI +from langchain_core.utils.function_calling import convert_to_openai_tool + +from agent.llm import register_llm_client +from agent.llm.base import BaseLLMClient + +from petercat_utils.data_class import MessageContent +from petercat_utils import get_env_variable + +DEEPSEEK_API_KEY = get_env_variable("DEEPSEEK_API_KEY") + + +@register_llm_client("deepseek") +class DeepSeekClient(BaseLLMClient): + _client: ChatOpenAI + + def __init__( + self, + temperature: Optional[float] = 0.2, + n: Optional[int] = 1, + top_p: Optional[float] = None, + max_tokens: Optional[int] = 1500, + streaming: Optional[bool] = False, + api_key: Optional[str] = DEEPSEEK_API_KEY, + ): + self._client = ChatOpenAI( + model_name="deepseek-chat", + temperature=temperature, + n=n, + top_p=top_p, + streaming=streaming, + max_tokens=max_tokens, + openai_api_key=api_key, + stream_usage=True, + openai_api_base="https://api.deepseek.com" + ) + + def get_client(self): + return self._client + + def get_tools(self, tools: List[Any]): + return [convert_to_openai_tool(tool) for tool in tools] + + def parse_content(self, content: List[MessageContent]): + print(f"parse_conent, content={content}") + return content \ No newline at end of file diff --git a/server/core/service/user_token_usage.py b/server/core/service/user_token_usage.py index 31ef2bd8..f9e9e24d 100644 --- a/server/core/service/user_token_usage.py +++ b/server/core/service/user_token_usage.py @@ -32,7 +32,7 @@ def top_bots(self, start_date: datetime.date, end_date: datetime.date): def top_users(self, start_date: datetime.date, end_date: datetime.date): return self.user_token_usage_dao.top_users(start_date=start_date, end_date=end_date) - + def get_user_token_usage_service(): return UserTokenUsageService() diff --git a/template.yml b/template.yml index 2f848f5a..cd02f4df 100644 --- a/template.yml +++ b/template.yml @@ -60,6 +60,10 @@ Parameters: Type: String Description: Gemini API Key Default: 1 + DeepSeekAPIKey: + Type: String + Description: DeepSeek API Key + Default: 1 SupabaseServiceKey: Type: String Description: Supabase Service Key @@ -129,7 +133,7 @@ Resources: PETERCAT_ENV: !Ref PetercatEnv X_GITHUB_SECRET_NAME: !Ref GithubSecretName STATIC_SECRET_NAME: !Ref StaticSecretName - LLM_TOKEN_SECRET_NAME: !Ref LLMTokenSecretName + LLM_TOKEN_SECRET_NAME: !Ref LLMTokenSecretName LLM_TOKEN_PUBLIC_NAME: !Ref LLMTokenPublicName STATIC_KEYPAIR_ID: !Ref StaticKeyPairId S3_TEMP_BUCKET_NAME: !Ref S3TempBucketName @@ -164,11 +168,11 @@ Resources: Resource: '*' - Sid: AllObjectActions Effect: Allow - Action: + Action: - s3:PutObject - s3:GetObject - s3:DeleteObject - Resource: + Resource: - !Sub 'arn:aws:s3:::${S3TempBucketName}/*' Tracing: Active Metadata: @@ -192,6 +196,7 @@ Resources: FASTAPI_SECRET_KEY: !Ref FastAPISecretKey OPENAI_API_KEY: !Ref OpenAIAPIKey GEMINI_API_KEY: !Ref GeminiAPIKey + DEEPSEEK_API_KEY: !Ref DeepSeekAPIKey SUPABASE_SERVICE_KEY: !Ref SupabaseServiceKey SUPABASE_URL: !Ref SupabaseUrl GITHUB_TOKEN: !Ref GitHubToken @@ -211,14 +216,14 @@ Resources: Resource: '*' - Sid: AllObjectActions Effect: Allow - Action: + Action: - s3:PutObject - s3:GetObject - s3:DeleteObject - Resource: + Resource: - !Sub 'arn:aws:s3:::${S3TempBucketName}/*' - SQSPollerPolicy: - QueueName: + QueueName: !Ref SQSQueueName Tracing: Active Metadata: