gitdeem commited on
Commit
34d42e2
1 Parent(s): 435eb82

Upload 8 files

Browse files
Files changed (5) hide show
  1. Dockerfile +2 -0
  2. app.ts +82 -0
  3. constant.ts +95 -0
  4. home.vue +0 -1
  5. toolbar.vue +32 -0
Dockerfile CHANGED
@@ -8,6 +8,8 @@ RUN git clone https://github.com/yokingma/search_with_ai.git /app
8
  COPY ./logo.png /app/web/src/assets/logo.png
9
  COPY ./logo.png /app/web/src/public/favicon.ico
10
  COPY ./home.vue /app/web/src/pages/home.vue
 
 
11
 
12
  WORKDIR /app
13
  RUN yarn install && yarn run build
 
8
  COPY ./logo.png /app/web/src/assets/logo.png
9
  COPY ./logo.png /app/web/src/public/favicon.ico
10
  COPY ./home.vue /app/web/src/pages/home.vue
11
+ COPY ./toolbar.vue /app/web/src/components/toolbar.vue
12
+ COPY ./constant.ts /app/backend/constant.ts
13
 
14
  WORKDIR /app
15
  RUN yarn install && yarn run build
app.ts ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Koa from 'koa';
2
+ import Router from '@koa/router';
3
+ import cors from '@koa/cors';
4
+ import { bodyParser } from '@koa/bodyparser';
5
+ import serve from 'koa-static';
6
+ import path from 'path';
7
+ import { whiteListMiddleware } from './middlewares';
8
+ import history from 'koa2-connect-history-api-fallback';
9
+ import { chatStreamController, localChatStreamController, localModelsController, modelsController, searchController, sogouSearchController } from './controllers';
10
+ import { initializeModels } from './constant'; // 请确保路径正确
11
+
12
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
13
+ // @ts-ignore
14
+ import dotenvx from '@dotenvx/dotenvx';
15
+ dotenvx.config();
16
+
17
+ const app = new Koa();
18
+ const router = new Router();
19
+
20
+ const port = process.env.PORT || 3000;
21
+
22
+ app.use(history({
23
+ index: '/index.html',
24
+ whiteList: ['/api']
25
+ }));
26
+
27
+ // static path
28
+ const staticPath = path.join(__dirname, '../web/build');
29
+ app.use(serve(staticPath, {
30
+ gzip: true,
31
+ index: 'index.html'
32
+ }));
33
+
34
+ app.use(cors({
35
+ origin: '*'
36
+ }));
37
+
38
+ app.use(bodyParser());
39
+
40
+ // Error handler
41
+ app.use(async (ctx, next) => {
42
+ try {
43
+ await next();
44
+ } catch(err) {
45
+ console.error('[server error]', err);
46
+ ctx.res.statusCode = 422;
47
+ ctx.body = err;
48
+ }
49
+ });
50
+
51
+ // router
52
+ app.use(router.routes()).use(router.allowedMethods());
53
+
54
+ // controller
55
+ router.post('/api/search', whiteListMiddleware(), searchController);
56
+ router.post('/api/sogou/search', sogouSearchController);
57
+ router.post('/api/chat', chatStreamController);
58
+ router.get('/api/models', modelsController);
59
+
60
+ // local llm
61
+ router.get('/api/local/models', localModelsController);
62
+ router.post('/api/local/chat', localChatStreamController);
63
+
64
+ // 创建异步启动函数
65
+ async function startApp() {
66
+ try {
67
+ // 初始化模型
68
+ await initializeModels();
69
+ console.log('Models initialized successfully');
70
+
71
+ // 启动服务器
72
+ app.listen(port, () => {
73
+ console.log(`Server is running on port ${port}`);
74
+ });
75
+ } catch (error) {
76
+ console.error('Failed to start the application:', error);
77
+ process.exit(1);
78
+ }
79
+ }
80
+
81
+ // 调用启动函数
82
+ startApp();
constant.ts ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { IModelInfo } from './interface';
2
+ import axios from 'axios';
3
+
4
+ // Search engine related. You don't really need to change this.
5
+ export const EndPoint = {
6
+ BING_SEARCH_V7_ENDPOINT: 'https://api.bing.microsoft.com/v7.0/search',
7
+ GOOGLE_SEARCH_ENDPOINT: 'https://www.googleapis.com/customsearch/v1'
8
+ };
9
+
10
+ export const BING_MKT = 'en-US';
11
+
12
+ // default timeout ms
13
+ export const DEFAULT_SEARCH_ENGINE_TIMEOUT = 20000;
14
+
15
+ // default search keywords
16
+ export const DefaultQuery = 'Who said \'live long and prosper';
17
+ export const DefaultSystem = 'You are a helpful assistant.';
18
+
19
+ // 创建一个异步函数来获取模型列表
20
+ async function fetchOpenAIModels(): Promise<string[]> {
21
+ try {
22
+ const response = await axios.get('https://api.deem.love/v1/models');
23
+ const data = response.data;
24
+ return data.data.map((model: { id: string }) => model.id);
25
+ } catch (error) {
26
+ console.error('获取模型列表失败:', error);
27
+ return [];
28
+ }
29
+ }
30
+
31
+ // 修改 Models 数组,将 'openai' 平台的模型设置为动态获取
32
+ export const Models: IModelInfo[] = [
33
+ {
34
+ platform: 'aliyun',
35
+ type: '',
36
+ models: ['qwen-max', 'qwen-max-1201', 'qwen-turbo', 'qwen-plus']
37
+ },
38
+ {
39
+ platform: 'openai',
40
+ type: 'openai',
41
+ //models: ['gpt-3.5-turbo', 'gpt-4-0125-preview', 'gpt-4-turbo-preview', 'gpt-4o']
42
+ models: [] // 初始为空数组,稍后动态填充
43
+ },
44
+ {
45
+ platform: 'baidu',
46
+ type: 'baidu',
47
+ models: ['eb-instant', 'completions_pro', 'ernie_bot_8k']
48
+ },
49
+ {
50
+ platform: 'google',
51
+ type: 'gemini',
52
+ models: ['gemini-pro', 'gemini-1.5-pro-latest']
53
+ },
54
+ {
55
+ platform: 'yi',
56
+ type: 'openai',
57
+ models: ['yi-34b-chat-0205', 'yi-34b-chat-200k']
58
+ },
59
+ {
60
+ platform: 'moonshot',
61
+ type: 'openai',
62
+ models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k']
63
+ },
64
+ {
65
+ platform: 'lepton',
66
+ type: 'openai',
67
+ models: ['llama2-7b', 'llama2-13b', 'llama2-70b', 'mixtral-8*7b', 'mixtral-8*22b']
68
+ },
69
+ {
70
+ platform: 'deepseek',
71
+ type: 'openai',
72
+ models: ['deepseek-chat', 'deepseek-coder']
73
+ },
74
+ {
75
+ platform: 'chatglm',
76
+ type: 'openai',
77
+ models: ['glm-4', 'glm-4v', 'glm-3-turbo']
78
+ },
79
+ {
80
+ platform: 'tencent',
81
+ type: 'tencent',
82
+ models: ['std', 'pro']
83
+ }
84
+ ];
85
+
86
+ // 创建一个初始化函数来更新 Models 数组
87
+ export async function initializeModels() {
88
+ const openAIModels = await fetchOpenAIModels();
89
+ Models = Models.map(platform => {
90
+ if (platform.platform === 'openai') {
91
+ return { ...platform, models: openAIModels };
92
+ }
93
+ return platform;
94
+ });
95
+ }
home.vue CHANGED
@@ -4,7 +4,6 @@
4
  <div class="flex items-center justify-center gap-2">
5
  <img :src="logoUrl" class="w-10" />
6
  <span class="text-3xl font-bold dark:text-gray-100">AI Search</span>
7
- <t-tag variant="light" class="text-xs text-gray-500"></t-tag>
8
  </div>
9
  <SearchInputBar :autofocus="true" :loading="false" @search="search" />
10
  <div class="my-2 flex flex-wrap items-center justify-center gap-4">
 
4
  <div class="flex items-center justify-center gap-2">
5
  <img :src="logoUrl" class="w-10" />
6
  <span class="text-3xl font-bold dark:text-gray-100">AI Search</span>
 
7
  </div>
8
  <SearchInputBar :autofocus="true" :loading="false" @search="search" />
9
  <div class="my-2 flex flex-wrap items-center justify-center gap-4">
toolbar.vue ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script setup lang="ts">
2
+ import { RiSettingsLine, RiGithubLine } from '@remixicon/vue';
3
+
4
+ type Emit = {
5
+ (e: 'show'): void;
6
+ }
7
+
8
+ const emits = defineEmits<Emit>();
9
+
10
+
11
+ </script>
12
+
13
+ <script lang="ts">
14
+ export default {
15
+ name: 'ToolBar'
16
+ };
17
+ </script>
18
+
19
+ <template>
20
+ <div class="fixed bottom-1/3 right-4 z-50 flex flex-col items-center justify-center gap-4">
21
+ <div class="flex w-9 justify-center gap-2 rounded-xl bg-gray-200 p-1 shadow-lg dark:bg-gray-600">
22
+ <t-button href="https://deem.love" target="_blank" shape="circle" theme="default">
23
+ <template #icon> <RiGithubLine /></template>
24
+ </t-button>
25
+ </div>
26
+ <div class="flex w-9 justify-center gap-2 rounded-xl bg-gray-200 p-1 shadow-lg dark:bg-gray-600">
27
+ <t-button shape="circle" theme="default" @click="emits('show')">
28
+ <template #icon> <RiSettingsLine /></template>
29
+ </t-button>
30
+ </div>
31
+ </div>
32
+ </template>