使用 vite 重构 renderer
This commit is contained in:
parent
19872c25b3
commit
535ab54128
@ -1,4 +0,0 @@
|
|||||||
> 1%
|
|
||||||
last 2 versions
|
|
||||||
not dead
|
|
||||||
not ie 11
|
|
0
renderer/.env.development
Normal file
0
renderer/.env.development
Normal file
0
renderer/.env.production
Normal file
0
renderer/.env.production
Normal file
@ -1,19 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
env: {
|
|
||||||
node: true,
|
|
||||||
},
|
|
||||||
extends: [
|
|
||||||
"plugin:vue/vue3-essential",
|
|
||||||
"eslint:recommended",
|
|
||||||
"@vue/typescript/recommended"
|
|
||||||
],
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 2020,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
|
||||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
|
||||||
'vue/multi-word-component-names': 'off'
|
|
||||||
},
|
|
||||||
};
|
|
30
renderer/.gitignore
vendored
30
renderer/.gitignore
vendored
@ -1,23 +1,31 @@
|
|||||||
.DS_Store
|
# Logs
|
||||||
node_modules
|
logs
|
||||||
/dist
|
*.log
|
||||||
|
|
||||||
|
|
||||||
# local env files
|
|
||||||
.env.local
|
|
||||||
.env.*.local
|
|
||||||
|
|
||||||
# Log files
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
|
||||||
*.suo
|
*.suo
|
||||||
*.ntvs*
|
*.ntvs*
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
*.tsbuildinfo
|
||||||
|
update.sh
|
@ -1,24 +1,33 @@
|
|||||||
# app
|
# test-vite
|
||||||
|
|
||||||
## Project setup
|
This template should help get you started developing with Vue 3 in Vite.
|
||||||
```
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
||||||
|
|
||||||
|
## Type Support for `.vue` Imports in TS
|
||||||
|
|
||||||
|
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
|
||||||
|
|
||||||
|
## Customize configuration
|
||||||
|
|
||||||
|
See [Vite Configuration Reference](https://vite.dev/config/).
|
||||||
|
|
||||||
|
## Project Setup
|
||||||
|
|
||||||
|
```sh
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compiles and hot-reloads for development
|
### Compile and Hot-Reload for Development
|
||||||
```
|
|
||||||
npm run serve
|
```sh
|
||||||
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compiles and minifies for production
|
### Type-Check, Compile and Minify for Production
|
||||||
```
|
|
||||||
|
```sh
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Lints and fixes files
|
|
||||||
```
|
|
||||||
npm run lint
|
|
||||||
```
|
|
||||||
|
|
||||||
### Customize configuration
|
|
||||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
presets: ["@vue/cli-plugin-babel/preset"],
|
|
||||||
};
|
|
1
renderer/env.d.ts
vendored
Normal file
1
renderer/env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
18
renderer/index.html
Normal file
18
renderer/index.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/favicon.png">
|
||||||
|
<link rel="stylesheet" href="/default-dark.css">
|
||||||
|
<link rel="stylesheet" href="/vscode.css">
|
||||||
|
<link rel="stylesheet" href="/mcp.css">
|
||||||
|
<link rel="stylesheet" href="/iconfont.css">
|
||||||
|
<link rel="stylesheet" href="/animation.css">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Vite App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
13649
renderer/package-lock.json
generated
13649
renderer/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "renderer",
|
"name": "test-vite",
|
||||||
"version": "0.1.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vite",
|
||||||
"build": "vue-cli-service build",
|
"serve:website": "vite --mode website",
|
||||||
"lint": "vue-cli-service lint"
|
"build": "run-p type-check \"build-only {@}\" --",
|
||||||
|
"build:website": "vite build --mode website",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"type-check": "vue-tsc --build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
@ -15,29 +20,22 @@
|
|||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"markdown-it-katex": "^2.0.3",
|
"markdown-it-katex": "^2.0.3",
|
||||||
"openai": "^4.93.0",
|
"openai": "^4.93.0",
|
||||||
|
"prismjs": "^1.30.0",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.5.13",
|
||||||
"vue-i18n": "^11.1.0",
|
"vue-i18n": "^11.1.0",
|
||||||
"vue-router": "^4.0.3"
|
"vue-router": "^4.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash": "^4.17.16",
|
"@tsconfig/node22": "^22.0.1",
|
||||||
"@types/markdown-it": "^14.1.2",
|
"@types/node": "^22.14.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
"@types/prismjs": "^1.26.5",
|
||||||
"@typescript-eslint/parser": "^5.4.0",
|
"@vitejs/plugin-vue": "^5.2.3",
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
"@vue/tsconfig": "^0.7.0",
|
||||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
"npm-run-all2": "^7.0.2",
|
||||||
"@vue/cli-plugin-router": "~5.0.0",
|
"typescript": "~5.8.0",
|
||||||
"@vue/cli-plugin-typescript": "~5.0.0",
|
"vite": "^6.2.4",
|
||||||
"@vue/cli-service": "~5.0.0",
|
"vite-plugin-vue-devtools": "^7.7.2",
|
||||||
"@vue/eslint-config-typescript": "^9.1.0",
|
"vue-tsc": "^2.2.8"
|
||||||
"eslint": "^7.32.0",
|
|
||||||
"eslint-config-prettier": "^8.3.0",
|
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
|
||||||
"eslint-plugin-vue": "^8.0.3",
|
|
||||||
"prettier": "^2.4.1",
|
|
||||||
"typescript": "^4.4.3",
|
|
||||||
"unplugin-auto-import": "^0.17.5",
|
|
||||||
"unplugin-vue-components": "^0.26.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
renderer/public/favicon.png
Normal file
BIN
renderer/public/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<svg viewBox="0 0 824 834" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<path id="path_1" d="M300 0C465.708 0 600 134.292 600 300L600 300C600 465.708 465.708 600 300 600L300 600C134.292 600 0 465.708 0 300L0 300C0 134.292 134.292 0 300 0Z" />
|
|
||||||
<linearGradient id="gradient_2" gradientUnits="userSpaceOnUse" x1="300" y1="0" x2="300" y2="600">
|
|
||||||
<stop offset="0" stop-color="#A1A7F6" />
|
|
||||||
<stop offset="1" stop-color="#FFFFFF" stop-opacity="0.2" />
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<g>
|
|
||||||
<g transform="translate(186 116)">
|
|
||||||
<use p4:href="#path_1" fill="#5A00FF" xmlns:p4="http://www.w3.org/1999/xlink" />
|
|
||||||
<use p4:href="#path_1" fill="url(#gradient_2)" xmlns:p4="http://www.w3.org/1999/xlink" />
|
|
||||||
</g>
|
|
||||||
<path d="M0 110.5C0 49.4725 49.4725 0 110.5 0C171.527 0 221 49.4725 221 110.5C221 171.527 171.527 221 110.5 221C49.4725 221 0 171.527 0 110.5Z" fill="#FFFFFF" fill-rule="evenodd" fill-opacity="0.431" transform="translate(445 458)" />
|
|
||||||
<path d="M0 55.5C0 24.8482 24.8482 0 55.5 0C86.1518 0 111 24.8482 111 55.5C111 86.1518 86.1518 111 55.5 111C24.8482 111 0 86.1518 0 55.5Z" fill="#FFFFFF" fill-rule="evenodd" fill-opacity="0.431" transform="translate(199 386)" />
|
|
||||||
<path d="M0 182.5C0 81.708 81.708 0 182.5 0C283.292 0 365 81.708 365 182.5C365 283.292 283.292 365 182.5 365C81.708 365 0 283.292 0 182.5Z" fill="#FFFFFF" fill-rule="evenodd" fill-opacity="0.424" transform="translate(339 156)" />
|
|
||||||
<path d="M0 57C0 25.5198 25.5198 0 57 0C88.4802 0 114 25.5198 114 57C114 88.4802 88.4802 114 57 114C25.5198 114 0 88.4802 0 57Z" fill="#FFFFFF" fill-rule="evenodd" fill-opacity="0.431" transform="translate(521 188)" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.7 KiB |
@ -1,22 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
||||||
<meta name="referrer" content="no-referrer">
|
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.svg">
|
|
||||||
<link rel="stylesheet" href="default-dark.css">
|
|
||||||
<link rel="stylesheet" href="vscode.css">
|
|
||||||
<link rel="stylesheet" href="mcp.css">
|
|
||||||
<link rel="stylesheet" href="iconfont.css">
|
|
||||||
<link rel="stylesheet" href="animation.css">
|
|
||||||
<title>OpenMCP Client</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -4,6 +4,7 @@
|
|||||||
<MainPanel></MainPanel>
|
<MainPanel></MainPanel>
|
||||||
|
|
||||||
<Tour v-if="!userHasReadGuide"/>
|
<Tour v-if="!userHasReadGuide"/>
|
||||||
|
<PasswordDialog v-if="password"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -17,14 +18,13 @@ import MainPanel from '@/components/main-panel/index.vue';
|
|||||||
import { setDefaultCss } from './hook/css';
|
import { setDefaultCss } from './hook/css';
|
||||||
import { greenLog, pinkLog } from './views/setting/util';
|
import { greenLog, pinkLog } from './views/setting/util';
|
||||||
import { useMessageBridge } from './api/message-bridge';
|
import { useMessageBridge } from './api/message-bridge';
|
||||||
import { doConnect, loadEnvVar } from './views/connect/connection';
|
import { initialise } from './views/connect/connection';
|
||||||
import { getTour, loadSetting } from './hook/setting';
|
|
||||||
import { loadPanels } from './hook/panel';
|
|
||||||
import { getPlatform } from './api/platform';
|
import { getPlatform } from './api/platform';
|
||||||
import Tour from '@/components/guide/tour.vue';
|
import Tour from '@/components/guide/tour.vue';
|
||||||
import { userHasReadGuide } from './components/guide/tour';
|
import { userHasReadGuide } from './components/guide/tour';
|
||||||
|
|
||||||
import { ElLoading } from 'element-plus';
|
import PasswordDialog from '@/components/password-dialog/index.vue';
|
||||||
|
import { privilegeStatus } from './components/password-dialog/status';
|
||||||
|
|
||||||
const bridge = useMessageBridge();
|
const bridge = useMessageBridge();
|
||||||
|
|
||||||
@ -37,23 +37,14 @@ bridge.addCommandListener('hello', data => {
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
onMounted(async () => {
|
const password = Boolean(import.meta.env.VITE_USE_PASSWORD);
|
||||||
const loading = ElLoading.service({
|
privilegeStatus.allow = !Boolean(password);
|
||||||
fullscreen: true,
|
|
||||||
lock: true,
|
|
||||||
text: 'Loading',
|
|
||||||
background: 'rgba(0, 0, 0, 0.7)'
|
|
||||||
});
|
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
// 初始化 css
|
// 初始化 css
|
||||||
setDefaultCss();
|
setDefaultCss();
|
||||||
|
|
||||||
document.addEventListener('click', () => {
|
|
||||||
Connection.showPanel = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
pinkLog('OpenMCP Client 启动');
|
pinkLog('OpenMCP Client 启动');
|
||||||
|
|
||||||
const platform = getPlatform();
|
const platform = getPlatform();
|
||||||
|
|
||||||
// 跳转到首页
|
// 跳转到首页
|
||||||
@ -65,29 +56,18 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 进行桥接
|
// 进行桥接
|
||||||
await bridge.awaitForWebsockt();
|
await bridge.awaitForWebsocket();
|
||||||
|
|
||||||
pinkLog('准备请求设置');
|
// 根据是否需要密码进行后续的选择
|
||||||
|
if (!privilegeStatus.allow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 加载全局设置
|
document.addEventListener('click', () => {
|
||||||
loadSetting();
|
Connection.showPanel = false;
|
||||||
|
|
||||||
// 设置环境变量
|
|
||||||
loadEnvVar();
|
|
||||||
|
|
||||||
// 获取引导状态
|
|
||||||
getTour();
|
|
||||||
|
|
||||||
// 尝试进行初始化连接
|
|
||||||
await doConnect({
|
|
||||||
namespace: platform,
|
|
||||||
updateCommandString: true
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// loading panels
|
await initialise();
|
||||||
await loadPanels();
|
|
||||||
|
|
||||||
loading.close();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
0
renderer/src/api/api.ts
Normal file
0
renderer/src/api/api.ts
Normal file
@ -1,10 +1,12 @@
|
|||||||
import { pinkLog, redLog } from '@/views/setting/util';
|
import { pinkLog, redLog } from '@/views/setting/util';
|
||||||
import { acquireVsCodeApi, electronApi, getPlatform } from './platform';
|
import { acquireVsCodeApi, electronApi, getPlatform } from './platform';
|
||||||
|
import { privilegeStatus } from '@/components/password-dialog/status';
|
||||||
|
|
||||||
export interface VSCodeMessage {
|
export interface VSCodeMessage {
|
||||||
command: string;
|
command: string;
|
||||||
data?: unknown;
|
data?: unknown;
|
||||||
callbackId?: string;
|
callbackId?: string;
|
||||||
|
password?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RestFulResponse {
|
export interface RestFulResponse {
|
||||||
@ -92,6 +94,7 @@ export class MessageBridge {
|
|||||||
this.postMessage = (message) => {
|
this.postMessage = (message) => {
|
||||||
if (this.ws?.readyState === WebSocket.OPEN) {
|
if (this.ws?.readyState === WebSocket.OPEN) {
|
||||||
console.log('send', message);
|
console.log('send', message);
|
||||||
|
message.password = privilegeStatus.password;
|
||||||
this.ws.send(JSON.stringify(message));
|
this.ws.send(JSON.stringify(message));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -105,7 +108,7 @@ export class MessageBridge {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async awaitForWebsockt() {
|
public async awaitForWebsocket() {
|
||||||
if (this.isConnected) {
|
if (this.isConnected) {
|
||||||
await this.isConnected;
|
await this.isConnected;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { ToolCallContent, ToolItem } from "@/hook/type";
|
import type { ToolCallContent, ToolItem } from "@/hook/type";
|
||||||
import { Ref, ref } from "vue";
|
import { type Ref, ref } from "vue";
|
||||||
|
|
||||||
import type { OpenAI } from 'openai';
|
import type { OpenAI } from 'openai';
|
||||||
type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk;
|
type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk;
|
||||||
|
@ -21,12 +21,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { provide, onMounted, onUnmounted, ref, defineEmits, defineProps, PropType, inject, Ref } from 'vue';
|
import { provide, onMounted, onUnmounted, ref, defineEmits, defineProps, type PropType, inject, type Ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import KRichTextarea from './rich-textarea.vue';
|
import KRichTextarea from './rich-textarea.vue';
|
||||||
import { tabs } from '../../panel';
|
import { tabs } from '../../panel';
|
||||||
import { ChatMessage, ChatStorage, MessageState, ToolCall, RichTextItem } from './chat';
|
import type { ChatMessage, ChatStorage, ToolCall, RichTextItem } from './chat';
|
||||||
|
import { MessageState } from './chat';
|
||||||
|
|
||||||
import { TaskLoop } from '../core/task-loop';
|
import { TaskLoop } from '../core/task-loop';
|
||||||
import { llmManager, llms } from '@/views/setting/llm';
|
import { llmManager, llms } from '@/views/setting/llm';
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, inject, ref } from 'vue';
|
import { defineComponent, inject, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ChatStorage } from '../chat';
|
import type { ChatStorage } from '../chat';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { createApp, inject, ref } from 'vue';
|
import { createApp, inject, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ChatStorage, EditorContext } from '../chat';
|
import type { ChatStorage, EditorContext } from '../chat';
|
||||||
import { PromptsGetResponse, PromptTemplate } from '@/hook/type';
|
import type { PromptsGetResponse, PromptTemplate } from '@/hook/type';
|
||||||
|
|
||||||
import PromptTemplates from '@/components/main-panel/prompt/prompt-templates.vue';
|
import PromptTemplates from '@/components/main-panel/prompt/prompt-templates.vue';
|
||||||
import PromptReader from '@/components/main-panel/prompt/prompt-reader.vue';
|
import PromptReader from '@/components/main-panel/prompt/prompt-reader.vue';
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { createApp, inject, ref } from 'vue';
|
import { createApp, inject, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ChatStorage, EditorContext } from '../chat';
|
import type { ChatStorage, EditorContext } from '../chat';
|
||||||
import { Resources, ResourcesReadResponse, ResourceTemplate } from '@/hook/type';
|
import type { Resources, ResourcesReadResponse, ResourceTemplate } from '@/hook/type';
|
||||||
|
|
||||||
import ResourceList from '@/components/main-panel/resource/resource-list.vue';
|
import ResourceList from '@/components/main-panel/resource/resource-list.vue';
|
||||||
import ResourceReader from '@/components/main-panel/resource/resouce-reader.vue';
|
import ResourceReader from '@/components/main-panel/resource/resouce-reader.vue';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ToolCallContent, ToolCallResponse } from "@/hook/type";
|
import type { ToolCallContent, ToolCallResponse } from "@/hook/type";
|
||||||
import { callTool } from "../../tool/tools";
|
import { callTool } from "../../tool/tools";
|
||||||
import { MessageState, ToolCall } from "../chat-box/chat";
|
import { MessageState, type ToolCall } from "../chat-box/chat";
|
||||||
|
|
||||||
export interface ToolCallResult {
|
export interface ToolCallResult {
|
||||||
state: MessageState;
|
state: MessageState;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { ref, type Ref } from "vue";
|
import { ref, type Ref } from "vue";
|
||||||
import { ToolCall, ChatStorage, getToolSchema, MessageState } from "../chat-box/chat";
|
import { type ToolCall, type ChatStorage, getToolSchema, MessageState } from "../chat-box/chat";
|
||||||
import { useMessageBridge, MessageBridge, createMessageBridge } from "@/api/message-bridge";
|
import { useMessageBridge, MessageBridge, createMessageBridge } from "@/api/message-bridge";
|
||||||
import type { OpenAI } from 'openai';
|
import type { OpenAI } from 'openai';
|
||||||
import { llmManager, llms } from "@/views/setting/llm";
|
import { llmManager, llms } from "@/views/setting/llm";
|
||||||
import { pinkLog, redLog } from "@/views/setting/util";
|
import { pinkLog, redLog } from "@/views/setting/util";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { handleToolCalls, ToolCallResult } from "./handle-tool-calls";
|
import { handleToolCalls, type ToolCallResult } from "./handle-tool-calls";
|
||||||
import { getPlatform } from "@/api/platform";
|
import { getPlatform } from "@/api/platform";
|
||||||
|
|
||||||
export type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk;
|
export type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { IExtraInfo } from "../chat-box/chat";
|
import type { IExtraInfo } from "../chat-box/chat";
|
||||||
|
|
||||||
export interface UsageStatistic {
|
export interface UsageStatistic {
|
||||||
input: number;
|
input: number;
|
||||||
|
@ -57,9 +57,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, defineComponent, defineProps, onUnmounted, computed, nextTick, watch, provide } from 'vue';
|
import { ref, onMounted, defineComponent, defineProps, onUnmounted, computed, nextTick, watch, provide } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ElMessage, ScrollbarInstance } from 'element-plus';
|
import { ElMessage, type ScrollbarInstance } from 'element-plus';
|
||||||
import { tabs } from '../panel';
|
import { tabs } from '../panel';
|
||||||
import { ChatMessage, ChatStorage, IRenderMessage, MessageState, ToolCall } from './chat-box/chat';
|
import type { ChatMessage, ChatStorage, IRenderMessage, ToolCall } from './chat-box/chat';
|
||||||
|
import { MessageState } from './chat-box/chat';
|
||||||
|
|
||||||
import * as Message from './message';
|
import * as Message from './message';
|
||||||
import ChatBox from './chat-box/index.vue';
|
import ChatBox from './chat-box/index.vue';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import Prism from "./prism";
|
import Prism from 'prismjs';
|
||||||
|
|
||||||
// 定义 escapeHtml 函数
|
// 定义 escapeHtml 函数
|
||||||
function escapeHtml(unsafe: string) {
|
function escapeHtml(unsafe: string) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const Prism: {
|
export const Prism: {
|
||||||
highlight: (code: string, language: any, lang: string) => string;
|
highlight: (code: string, language: any, lang: string) => string;
|
||||||
languages: Record<string, any>;
|
languages: Record<string, any>;
|
||||||
// 添加其他需要的类型定义
|
// 添加其他需要的类型定义
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineProps, ref, PropType, inject } from 'vue';
|
import { defineProps, ref, type PropType, inject } from 'vue';
|
||||||
import { tabs } from '../../panel';
|
import { tabs } from '../../panel';
|
||||||
import type { ChatStorage, IRenderMessage } from '../chat-box/chat';
|
import type { ChatStorage, IRenderMessage } from '../chat-box/chat';
|
||||||
|
|
||||||
|
@ -27,10 +27,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useMessageBridge } from '@/api/message-bridge';
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
import { CasualRestAPI, PromptTemplate, PromptsListResponse } from '@/hook/type';
|
import type { CasualRestAPI, PromptTemplate, PromptsListResponse } from '@/hook/type';
|
||||||
import { onMounted, onUnmounted, defineProps, defineEmits, reactive } from 'vue';
|
import { onMounted, onUnmounted, defineProps, defineEmits, reactive } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { promptsManager, PromptStorage } from './prompts';
|
import { promptsManager, type PromptStorage } from './prompts';
|
||||||
import { tabs } from '../panel';
|
import { tabs } from '../panel';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { PromptsGetResponse, PromptTemplate } from '@/hook/type';
|
import type { PromptsGetResponse, PromptTemplate } from '@/hook/type';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
export const promptsManager = reactive<{
|
export const promptsManager = reactive<{
|
||||||
|
@ -38,8 +38,8 @@ import { defineComponent, defineProps, watch, ref, computed, reactive, defineEmi
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import type { FormInstance, FormRules } from 'element-plus';
|
import type { FormInstance, FormRules } from 'element-plus';
|
||||||
import { tabs } from '../panel';
|
import { tabs } from '../panel';
|
||||||
import { parseResourceTemplate, resourcesManager, ResourceStorage } from './resources';
|
import { parseResourceTemplate, resourcesManager, type ResourceStorage } from './resources';
|
||||||
import { CasualRestAPI, ResourcesReadResponse } from '@/hook/type';
|
import type{ CasualRestAPI, ResourcesReadResponse } from '@/hook/type';
|
||||||
import { useMessageBridge } from '@/api/message-bridge';
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
import { getDefaultValue, normaliseJavascriptType } from '@/hook/mcp';
|
import { getDefaultValue, normaliseJavascriptType } from '@/hook/mcp';
|
||||||
|
|
||||||
|
@ -30,10 +30,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useMessageBridge } from '@/api/message-bridge';
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
import { CasualRestAPI, ResourceTemplate, ResourceTemplatesListResponse } from '@/hook/type';
|
import type { CasualRestAPI, ResourceTemplate, ResourceTemplatesListResponse } from '@/hook/type';
|
||||||
import { onMounted, onUnmounted, defineProps, ref, reactive } from 'vue';
|
import { onMounted, onUnmounted, defineProps, ref, reactive } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { resourcesManager, ResourceStorage } from './resources';
|
import { resourcesManager, type ResourceStorage } from './resources';
|
||||||
import { tabs } from '../panel';
|
import { tabs } from '../panel';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
@ -27,10 +27,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useMessageBridge } from '@/api/message-bridge';
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
import { CasualRestAPI, Resources, ResourcesListResponse } from '@/hook/type';
|
import type { CasualRestAPI, Resources, ResourcesListResponse } from '@/hook/type';
|
||||||
import { onMounted, onUnmounted, defineProps, defineEmits, reactive } from 'vue';
|
import { onMounted, onUnmounted, defineProps, defineEmits, reactive } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { resourcesManager, ResourceStorage } from './resources';
|
import { resourcesManager, type ResourceStorage } from './resources';
|
||||||
import { tabs } from '../panel';
|
import { tabs } from '../panel';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ResourcesReadResponse, ResourceTemplate, Resources } from '@/hook/type';
|
import type { ResourcesReadResponse, ResourceTemplate, Resources } from '@/hook/type';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,10 +31,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useMessageBridge } from '@/api/message-bridge';
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
import { CasualRestAPI, ToolsListResponse } from '@/hook/type';
|
import type { CasualRestAPI, ToolsListResponse } from '@/hook/type';
|
||||||
import { onMounted, onUnmounted, defineProps } from 'vue';
|
import { onMounted, onUnmounted, defineProps } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { toolsManager, ToolStorage } from './tools';
|
import { toolsManager, type ToolStorage } from './tools';
|
||||||
import { tabs } from '../panel';
|
import { tabs } from '../panel';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useMessageBridge } from '@/api/message-bridge';
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
import { mcpSetting } from '@/hook/mcp';
|
import { mcpSetting } from '@/hook/mcp';
|
||||||
import { ToolsListResponse, ToolCallResponse, CasualRestAPI } from '@/hook/type';
|
import type { ToolsListResponse, ToolCallResponse, CasualRestAPI } from '@/hook/type';
|
||||||
import { pinkLog } from '@/views/setting/util';
|
import { pinkLog } from '@/views/setting/util';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
|
55
renderer/src/components/password-dialog/index.vue
Normal file
55
renderer/src/components/password-dialog/index.vue
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="请输入密码" :close-on-click-modal="false" :close-on-press-escape="false"
|
||||||
|
:show-close="false" width="30%" top="20vh">
|
||||||
|
<br>
|
||||||
|
<el-input v-model="privilegeStatus.password"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
@keyup.enter.prevent="handleSubmit"
|
||||||
|
/>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary" @click="handleSubmit">确认</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { privilegeStatus } from './status';
|
||||||
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
|
import { initialise } from '@/views/connect/connection';
|
||||||
|
|
||||||
|
const dialogVisible = ref(true);
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
const bridge = useMessageBridge();
|
||||||
|
const res = await bridge.commandRequest('ciallo', { password: privilegeStatus.password });
|
||||||
|
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('密码验证成功,欢迎回来锦恢');
|
||||||
|
dialogVisible.value = false;
|
||||||
|
|
||||||
|
initialise();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ElMessage.error('密码验证失败,请重新输入');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
dialogVisible.value = true;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.el-dialog {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
</style>
|
6
renderer/src/components/password-dialog/status.ts
Normal file
6
renderer/src/components/password-dialog/status.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { reactive } from "vue";
|
||||||
|
|
||||||
|
export const privilegeStatus = reactive({
|
||||||
|
allow: true,
|
||||||
|
password: ''
|
||||||
|
});
|
@ -1,4 +1,4 @@
|
|||||||
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
|
import { createRouter, createWebHistory, type RouteRecordRaw } from "vue-router";
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
{
|
{
|
||||||
@ -33,7 +33,7 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(process.env.BASE_URL),
|
history: createWebHistory('/'),
|
||||||
routes,
|
routes,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { useMessageBridge } from '@/api/message-bridge';
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { pinkLog } from '../setting/util';
|
import { pinkLog } from '../setting/util';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElLoading, ElMessage } from 'element-plus';
|
||||||
import { OpenMcpSupportPlatform } from '@/api/platform';
|
import { getPlatform, type OpenMcpSupportPlatform } from '@/api/platform';
|
||||||
|
import { getTour, loadSetting } from '@/hook/setting';
|
||||||
|
import { loadPanels } from '@/hook/panel';
|
||||||
|
|
||||||
export const connectionMethods = reactive({
|
export const connectionMethods = reactive({
|
||||||
current: 'STDIO',
|
current: 'STDIO',
|
||||||
@ -98,7 +100,7 @@ export async function doConnect(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
connectionMethods.current = 'SSE';
|
connectionMethods.current = 'SSE';
|
||||||
connectionArgs.urlString = connectionItem.url;
|
connectionArgs.urlString = connectionItem.url || '';
|
||||||
|
|
||||||
if (connectionArgs.urlString.length === 0) {
|
if (connectionArgs.urlString.length === 0) {
|
||||||
return;
|
return;
|
||||||
@ -346,3 +348,36 @@ export async function handleEnvSwitch(enabled: boolean) {
|
|||||||
export async function loadEnvVar() {
|
export async function loadEnvVar() {
|
||||||
return await handleEnvSwitch(true);
|
return await handleEnvSwitch(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function initialise() {
|
||||||
|
|
||||||
|
pinkLog('准备请求设置');
|
||||||
|
|
||||||
|
const loading = ElLoading.service({
|
||||||
|
fullscreen: true,
|
||||||
|
lock: true,
|
||||||
|
text: 'Loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
});
|
||||||
|
const platform = getPlatform();
|
||||||
|
|
||||||
|
// 加载全局设置
|
||||||
|
loadSetting();
|
||||||
|
|
||||||
|
// 设置环境变量
|
||||||
|
await loadEnvVar();
|
||||||
|
|
||||||
|
// 获取引导状态
|
||||||
|
await getTour();
|
||||||
|
|
||||||
|
// 尝试进行初始化连接
|
||||||
|
await doConnect({
|
||||||
|
namespace: platform,
|
||||||
|
updateCommandString: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// loading panels
|
||||||
|
await loadPanels();
|
||||||
|
|
||||||
|
loading.close();
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { ChatStorage } from '@/components/main-panel/chat/chat-box/chat';
|
import type { ChatStorage } from '@/components/main-panel/chat/chat-box/chat';
|
||||||
import { TaskLoop } from '@/components/main-panel/chat/core/task-loop';
|
import { TaskLoop } from '@/components/main-panel/chat/core/task-loop';
|
||||||
import { llmManager } from './llm';
|
import { llmManager } from './llm';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
@ -60,7 +60,7 @@ export async function makeSimpleTalk() {
|
|||||||
await loop.start(chatStorage, testMessage);
|
await loop.start(chatStorage, testMessage);
|
||||||
|
|
||||||
const costTime = (performance.now() - startTime!) / 1000;
|
const costTime = (performance.now() - startTime!) / 1000;
|
||||||
const message = chatStorage.messages.at(-1);
|
const message = chatStorage.messages[chatStorage.messages.length - 1];
|
||||||
console.log(chatStorage.messages);
|
console.log(chatStorage.messages);
|
||||||
|
|
||||||
if (message?.extraInfo) {
|
if (message?.extraInfo) {
|
||||||
@ -70,5 +70,4 @@ export async function makeSimpleTalk() {
|
|||||||
simpleTestResult.tps = (total / costTime).toFixed(2);
|
simpleTestResult.tps = (total / costTime).toFixed(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { markRaw, reactive } from 'vue';
|
import { markRaw, reactive } from 'vue';
|
||||||
import { createTab, debugModes, tabs } from '@/components/main-panel/panel';
|
import { createTab, debugModes, tabs } from '@/components/main-panel/panel';
|
||||||
import { ToolStorage } from '@/components/main-panel/tool/tools';
|
import type { ToolStorage } from '@/components/main-panel/tool/tools';
|
||||||
import { ToolCall } from '@/components/main-panel/chat/chat-box/chat';
|
import type { ToolCall } from '@/components/main-panel/chat/chat-box/chat';
|
||||||
|
|
||||||
import I18n from '@/i18n';
|
import I18n from '@/i18n';
|
||||||
const { t } = I18n.global;
|
const { t } = I18n.global;
|
||||||
|
19
renderer/tsconfig.app.json
Normal file
19
renderer/tsconfig.app.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||||
|
"include": [
|
||||||
|
"env.d.ts",
|
||||||
|
"src/**/*",
|
||||||
|
"src/**/*.vue"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"src/**/__tests__/*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./src/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,41 +1,17 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "esnext",
|
|
||||||
"module": "nodenext",
|
|
||||||
"strict": true,
|
|
||||||
"jsx": "preserve",
|
|
||||||
"moduleResolution": "nodenext",
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"useDefineForClassFields": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"types": [
|
|
||||||
"webpack-env"
|
|
||||||
],
|
|
||||||
"paths": {
|
|
||||||
"@/*": [
|
|
||||||
"src/*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"lib": [
|
"lib": [
|
||||||
"esnext",
|
"es2022",
|
||||||
"dom",
|
"dom"
|
||||||
"dom.iterable",
|
|
||||||
"scripthost"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"files": [],
|
||||||
"src/**/*.ts",
|
"references": [
|
||||||
"src/**/*.tsx",
|
{
|
||||||
"src/**/*.vue",
|
"path": "./tsconfig.node.json"
|
||||||
"tests/**/*.ts",
|
},
|
||||||
"tests/**/*.tsx"
|
{
|
||||||
],
|
"path": "./tsconfig.app.json"
|
||||||
"exclude": [
|
}
|
||||||
"node_modules"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
20
renderer/tsconfig.node.json
Normal file
20
renderer/tsconfig.node.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/node22/tsconfig.json",
|
||||||
|
"include": [
|
||||||
|
"vite.config.*",
|
||||||
|
"vitest.config.*",
|
||||||
|
"cypress.config.*",
|
||||||
|
"nightwatch.conf.*",
|
||||||
|
"playwright.config.*",
|
||||||
|
"eslint.config.*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": true,
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"types": [
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
18
renderer/vite.config.ts
Normal file
18
renderer/vite.config.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { fileURLToPath, URL } from 'node:url'
|
||||||
|
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
vueDevTools(),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
@ -1,54 +0,0 @@
|
|||||||
const { defineConfig } = require("@vue/cli-service");
|
|
||||||
|
|
||||||
function getPublicPath() {
|
|
||||||
const env = process.env.NODE_ENV;
|
|
||||||
if (env === 'production') {
|
|
||||||
return '';
|
|
||||||
} else if (env === 'kirigaya') {
|
|
||||||
return '/mcp';
|
|
||||||
} else {
|
|
||||||
return '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = defineConfig({
|
|
||||||
transpileDependencies: true,
|
|
||||||
publicPath: process.env.NODE_ENV === 'production' ? '' : '/',
|
|
||||||
configureWebpack: {
|
|
||||||
optimization: {
|
|
||||||
splitChunks: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
chainWebpack: config => {
|
|
||||||
// 删除所有预设的代码分割规则
|
|
||||||
config.optimization.delete('splitChunks');
|
|
||||||
|
|
||||||
// 确保路由组件同步加载
|
|
||||||
config.plugins.delete('prefetch');
|
|
||||||
config.plugins.delete('preload');
|
|
||||||
|
|
||||||
// 删除 public 下指定的 css 文件
|
|
||||||
config.plugin('copy').tap(args => {
|
|
||||||
args[0].patterns = args[0].patterns.map((pattern) => {
|
|
||||||
if (pattern.from === "public") {
|
|
||||||
// 忽略指定的 CSS 文件
|
|
||||||
pattern.globOptions = {
|
|
||||||
ignore: [
|
|
||||||
"vscode.css",
|
|
||||||
"default-light.css",
|
|
||||||
"default-dark.css",
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return pattern;
|
|
||||||
});
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
css: {
|
|
||||||
extract: false
|
|
||||||
},
|
|
||||||
devServer: {
|
|
||||||
port: 8081
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,22 +0,0 @@
|
|||||||
const AutoImport = require('unplugin-auto-import/webpack')
|
|
||||||
const Components = require('unplugin-vue-components/webpack')
|
|
||||||
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
plugins: [
|
|
||||||
AutoImport({
|
|
||||||
resolvers: [ElementPlusResolver()],
|
|
||||||
}),
|
|
||||||
Components({
|
|
||||||
resolvers: [ElementPlusResolver()],
|
|
||||||
}),
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false,
|
|
||||||
})
|
|
||||||
],
|
|
||||||
resolve: {
|
|
||||||
fallback: {
|
|
||||||
"stream": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
3
service/.gitignore
vendored
3
service/.gitignore
vendored
@ -26,4 +26,5 @@ setting.json
|
|||||||
|
|
||||||
*.traineddata
|
*.traineddata
|
||||||
.env
|
.env
|
||||||
tabs.example-servers_puppeteer.json
|
tabs.*
|
||||||
|
update.sh
|
@ -1,77 +0,0 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* source: https://gist.github.com/Laci21/9dd074f3a5a461ab04adb7db678534d3
|
|
||||||
* issue: https://github.com/modelcontextprotocol/typescript-sdk/issues/217
|
|
||||||
*
|
|
||||||
* This script fixes the MCP SDK issue with pkce-challenge ES Module
|
|
||||||
* It replaces the static require with a dynamic import in the auth.js file
|
|
||||||
*/
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
// Path to the file that needs patching
|
|
||||||
const authFilePath = path.resolve(
|
|
||||||
__dirname,
|
|
||||||
'node_modules',
|
|
||||||
'@modelcontextprotocol',
|
|
||||||
'sdk',
|
|
||||||
'dist',
|
|
||||||
'cjs',
|
|
||||||
'client',
|
|
||||||
'auth.js'
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('Checking if MCP SDK patch is needed...');
|
|
||||||
|
|
||||||
// Check if the file exists
|
|
||||||
if (!fs.existsSync(authFilePath)) {
|
|
||||||
console.error(`Error: File not found at ${authFilePath}`);
|
|
||||||
console.log('Make sure you have installed @modelcontextprotocol/sdk package');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the file content
|
|
||||||
const fileContent = fs.readFileSync(authFilePath, 'utf8');
|
|
||||||
|
|
||||||
// Check if the file already contains our patch
|
|
||||||
if (fileContent.includes('loadPkceChallenge')) {
|
|
||||||
console.log('MCP SDK is already patched!');
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the file contains the problematic require
|
|
||||||
if (!fileContent.includes("require(\"pkce-challenge\")")) {
|
|
||||||
console.log('The MCP SDK file does not contain the expected require statement.');
|
|
||||||
console.log('This patch may not be needed or the SDK has been updated.');
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Applying patch to MCP SDK...');
|
|
||||||
|
|
||||||
// The code to replace the problematic require
|
|
||||||
const requireLine = "const pkce_challenge_1 = __importDefault(require(\"pkce-challenge\"));";
|
|
||||||
const replacementCode = `let pkce_challenge_1 = { default: null };
|
|
||||||
async function loadPkceChallenge() {
|
|
||||||
if (!pkce_challenge_1.default) {
|
|
||||||
const mod = await import("pkce-challenge");
|
|
||||||
pkce_challenge_1.default = mod.default;
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
|
|
||||||
// Replace the require line
|
|
||||||
let patchedContent = fileContent.replace(requireLine, replacementCode);
|
|
||||||
|
|
||||||
// Replace the function call to add the loading step
|
|
||||||
const challengeCall = "const challenge = await (0, pkce_challenge_1.default)();";
|
|
||||||
const replacementCall = "await loadPkceChallenge();\n const challenge = await pkce_challenge_1.default();";
|
|
||||||
patchedContent = patchedContent.replace(challengeCall, replacementCall);
|
|
||||||
|
|
||||||
// Write the patched content back to the file
|
|
||||||
fs.writeFileSync(authFilePath, patchedContent, 'utf8');
|
|
||||||
|
|
||||||
console.log('✅ MCP SDK patched successfully!');
|
|
||||||
console.log('The patch changes:');
|
|
||||||
console.log('1. Replaced static require with dynamic import for pkce-challenge');
|
|
||||||
console.log('2. Added async loading function to handle the import');
|
|
||||||
console.log('\nYou should now be able to run the application without ESM errors.');
|
|
@ -98,7 +98,7 @@ function updateConnectionOption(data: any) {
|
|||||||
const devHome = path.join(__dirname, '..', '..');
|
const devHome = path.join(__dirname, '..', '..');
|
||||||
setRunningCWD(devHome);
|
setRunningCWD(devHome);
|
||||||
|
|
||||||
wss.on('connection', ws => {
|
wss.on('connection', (ws: any) => {
|
||||||
|
|
||||||
// 仿造 webview 进行统一接口访问
|
// 仿造 webview 进行统一接口访问
|
||||||
const webview = new VSCodeWebViewLike(ws);
|
const webview = new VSCodeWebViewLike(ws);
|
||||||
|
@ -57,6 +57,10 @@ export async function connectService(
|
|||||||
return connectResult;
|
return connectResult;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
|
console.log('meet error');
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
|
||||||
// TODO: 这边获取到的 error 不够精致,如何才能获取到更加精准的错误
|
// TODO: 这边获取到的 error 不够精致,如何才能获取到更加精准的错误
|
||||||
// 比如 error: Failed to spawn: `server.py`
|
// 比如 error: Failed to spawn: `server.py`
|
||||||
// Caused by: No such file or directory (os error 2)
|
// Caused by: No such file or directory (os error 2)
|
||||||
|
200
service/src/server.ts
Normal file
200
service/src/server.ts
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
import WebSocket from 'ws';
|
||||||
|
import pino from 'pino';
|
||||||
|
|
||||||
|
import { routeMessage } from './common/router';
|
||||||
|
import { VSCodeWebViewLike } from './hook/adapter';
|
||||||
|
import path from 'node:path';
|
||||||
|
import * as fs from 'node:fs';
|
||||||
|
import { setRunningCWD } from './hook/setting';
|
||||||
|
import { exit } from 'node:process';
|
||||||
|
|
||||||
|
export interface VSCodeMessage {
|
||||||
|
command: string;
|
||||||
|
data?: unknown;
|
||||||
|
callbackId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const logger = pino({
|
||||||
|
transport: {
|
||||||
|
target: 'pino-pretty', // 启用 pino-pretty
|
||||||
|
options: {
|
||||||
|
colorize: true, // 开启颜色
|
||||||
|
levelFirst: true, // 先打印日志级别
|
||||||
|
translateTime: 'SYS:yyyy-mm-dd HH:MM:ss', // 格式化时间
|
||||||
|
ignore: 'pid,hostname', // 忽略部分字段
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export type MessageHandler = (message: VSCodeMessage) => void;
|
||||||
|
const wss = new (WebSocket as any).Server({ port: 8282 });
|
||||||
|
|
||||||
|
interface IStdioLaunchSignature {
|
||||||
|
type: 'stdio';
|
||||||
|
commandString: string;
|
||||||
|
cwd: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISSELaunchSignature {
|
||||||
|
type:'sse';
|
||||||
|
url: string;
|
||||||
|
oauth: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ILaunchSigature = IStdioLaunchSignature | ISSELaunchSignature;
|
||||||
|
|
||||||
|
function refreshConnectionOption(envPath: string) {
|
||||||
|
const defaultOption = {
|
||||||
|
type:'stdio',
|
||||||
|
command: 'mcp',
|
||||||
|
args: ['run', 'main.py'],
|
||||||
|
cwd: '../server'
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.writeFileSync(envPath, JSON.stringify(defaultOption, null, 4));
|
||||||
|
|
||||||
|
return defaultOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInitConnectionOption() {
|
||||||
|
const envPath = path.join(__dirname, '..', '.env');
|
||||||
|
|
||||||
|
if (!fs.existsSync(envPath)) {
|
||||||
|
return refreshConnectionOption(envPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const option = JSON.parse(fs.readFileSync(envPath, 'utf-8'));
|
||||||
|
return option;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('读取 .env 配置文件');
|
||||||
|
return refreshConnectionOption(envPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(path.join(__dirname, '..', '.env.website.local'))) {
|
||||||
|
console.log('.env.website.local 不存在!');
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const authPassword = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '.env.website.local'), 'utf-8')).password;
|
||||||
|
|
||||||
|
function updateConnectionOption(data: any) {
|
||||||
|
const envPath = path.join(__dirname, '..', '.env');
|
||||||
|
|
||||||
|
if (data.connectionType === 'STDIO') {
|
||||||
|
const connectionItem = {
|
||||||
|
type: 'stdio',
|
||||||
|
command: data.command,
|
||||||
|
args: data.args,
|
||||||
|
cwd: data.cwd.replace(/\\/g, '/')
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.writeFileSync(envPath, JSON.stringify(connectionItem, null, 4));
|
||||||
|
} else {
|
||||||
|
const connectionItem = {
|
||||||
|
type: 'sse',
|
||||||
|
url: data.url,
|
||||||
|
oauth: data.oauth
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.writeFileSync(envPath, JSON.stringify(connectionItem, null, 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const devHome = path.join(__dirname, '..', '..');
|
||||||
|
setRunningCWD(devHome);
|
||||||
|
|
||||||
|
wss.on('connection', (ws: any) => {
|
||||||
|
|
||||||
|
// 仿造 webview 进行统一接口访问
|
||||||
|
const webview = new VSCodeWebViewLike(ws);
|
||||||
|
|
||||||
|
// 先发送成功建立的消息
|
||||||
|
webview.postMessage({
|
||||||
|
command: 'hello',
|
||||||
|
data: {
|
||||||
|
version: '0.0.1',
|
||||||
|
name: '消息桥连接完成'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const option = getInitConnectionOption();
|
||||||
|
|
||||||
|
// 注册消息接受的管线
|
||||||
|
webview.onDidReceiveMessage(message => {
|
||||||
|
logger.info(`command: [${message.command || 'No Command'}]`);
|
||||||
|
const { command, data, password } = message;
|
||||||
|
|
||||||
|
console.log(command, data);
|
||||||
|
|
||||||
|
|
||||||
|
if (command === 'ciallo') {
|
||||||
|
if (data.password === authPassword) {
|
||||||
|
webview.postMessage({
|
||||||
|
command,
|
||||||
|
data: {
|
||||||
|
code: 200,
|
||||||
|
msg: 'ciallo'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
webview.postMessage({
|
||||||
|
command,
|
||||||
|
data: {
|
||||||
|
code: 403,
|
||||||
|
msg: '没有权限'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password !== authPassword) {
|
||||||
|
webview.postMessage({
|
||||||
|
command,
|
||||||
|
data: {
|
||||||
|
code: 403,
|
||||||
|
msg: '没有权限'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case 'web/launch-signature':
|
||||||
|
const launchResultMessage: ILaunchSigature = option.type === 'stdio' ?
|
||||||
|
{
|
||||||
|
type: 'stdio',
|
||||||
|
commandString: option.command + ' ' + option.args.join(' '),
|
||||||
|
cwd: option.cwd || ''
|
||||||
|
} :
|
||||||
|
{
|
||||||
|
type: 'sse',
|
||||||
|
url: option.url,
|
||||||
|
oauth: option.oauth || ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const launchResult = {
|
||||||
|
code: 200,
|
||||||
|
msg: launchResultMessage
|
||||||
|
};
|
||||||
|
|
||||||
|
webview.postMessage({
|
||||||
|
command: 'web/launch-signature',
|
||||||
|
data: launchResult
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'web/update-connection-sigature':
|
||||||
|
updateConnectionOption(data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
routeMessage(command, data, webview);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -17,7 +17,6 @@ export class SettingController {
|
|||||||
|
|
||||||
@Controller('setting/load')
|
@Controller('setting/load')
|
||||||
async loadSetting(client: RequestClientType, data: any, webview: PostMessageble) {
|
async loadSetting(client: RequestClientType, data: any, webview: PostMessageble) {
|
||||||
console.log('enter loading');
|
|
||||||
|
|
||||||
const config = loadSetting();
|
const config = loadSetting();
|
||||||
return {
|
return {
|
||||||
@ -41,7 +40,6 @@ export class SettingController {
|
|||||||
|
|
||||||
@Controller('setting/get-tour')
|
@Controller('setting/get-tour')
|
||||||
async getTourController(client: RequestClientType, data: any, webview: PostMessageble) {
|
async getTourController(client: RequestClientType, data: any, webview: PostMessageble) {
|
||||||
console.log('enter');
|
|
||||||
|
|
||||||
const { userHasReadGuide } = getTour();
|
const { userHasReadGuide } = getTour();
|
||||||
|
|
||||||
|
@ -1,175 +0,0 @@
|
|||||||
{
|
|
||||||
"currentIndex": 2,
|
|
||||||
"tabs": [
|
|
||||||
{
|
|
||||||
"name": "资源",
|
|
||||||
"icon": "icon-file",
|
|
||||||
"type": "blank",
|
|
||||||
"componentIndex": 0,
|
|
||||||
"storage": {
|
|
||||||
"formData": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "工具",
|
|
||||||
"icon": "icon-tool",
|
|
||||||
"type": "blank",
|
|
||||||
"componentIndex": 2,
|
|
||||||
"storage": {
|
|
||||||
"currentToolName": "image_crawler",
|
|
||||||
"formData": {
|
|
||||||
"key_word": "",
|
|
||||||
"image_num": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "交互测试",
|
|
||||||
"icon": "icon-robot",
|
|
||||||
"type": "blank",
|
|
||||||
"componentIndex": 3,
|
|
||||||
"storage": {
|
|
||||||
"messages": [
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": "帮我找几张 明日方舟 m3 的图片,渲染出来",
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730609368,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "assistant",
|
|
||||||
"content": "",
|
|
||||||
"tool_calls": [
|
|
||||||
{
|
|
||||||
"id": "call_660r5ehyhh86cjtqnako0mnt",
|
|
||||||
"index": 0,
|
|
||||||
"type": "function",
|
|
||||||
"function": {
|
|
||||||
"name": "image_crawler",
|
|
||||||
"arguments": "{\"key_word\":\"明日方舟 m3\",\"image_num\":5}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730610263,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "tool",
|
|
||||||
"tool_call_id": "call_660r5ehyhh86cjtqnako0mnt",
|
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"text": "[ImageResult(url='https://gd-hbimg.huaban.com/0c97d53a94f333fad66ca70f32601d8c34c2d4db8f53e0-netl2f_fw658', title='', source='bing'), ImageResult(url='https://ts1.tc.mm.bing.net/th/id/R-C.db1a4364345d8b082d4de48cae32ae05?rik=rhE9iKxzhvwzDg', title='', source='bing'), ImageResult(url='https://gd-hbimg.huaban.com/a4b669d3e68da3ee91a12afe7a0bd689038bdc262aece-yasxcI_fw658', title='', source='bing'), ImageResult(url='https://ts1.tc.mm.bing.net/th/id/R-C.d9dc5fcd4b628e805d4b6a0edb0f9a48?rik=RiUbfVRpViaT%2fw', title='', source='bing'), ImageResult(url='https://gd-hbimg.huaban.com/205d12dbf22aec83ff34bd533616575f0939b561136c6-jwF7XH_fw658', title='', source='bing')]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730610855,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "assistant",
|
|
||||||
"content": "以下是根据关键词“明日方舟 m3”找到的图片:\n\n1. \n2. \n3. \n4. \n5. \n\n你可以点击链接查看这些图片。",
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730615968,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": "图源是哪里",
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730806510,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "assistant",
|
|
||||||
"content": "这些图片的来源是Bing搜索引擎和Huaban网站。具体来源如下:\n\n1. **Bing**:\n - [Image 2](https://ts1.tc.mm.bing.net/th/id/R-C.db1a4364345d8b082d4de48cae32ae05?rik=rhE9iKxzhvwzDg)\n - [Image 4](https://ts1.tc.mm.bing.net/th/id/R-C.d9dc5fcd4b628e805d4b6a0edb0f9a48?rik=RiUbfVRpViaT%2fw)\n\n2. **Huaban**:\n - [Image 1](https://gd-hbimg.huaban.com/0c97d53a94f333fad66ca70f32601d8c34c2d4db8f53e0-netl2f_fw658)\n - [Image 3](https://gd-hbimg.huaban.com/a4b669d3e68da3ee91a12afe7a0bd689038bdc262aece-yasxcI_fw658)\n - [Image 5](https://gd-hbimg.huaban.com/205d12dbf22aec83ff34bd533616575f0939b561136c6-jwF7XH_fw658)\n\n你可以通过点击链接查看图片的详细信息。",
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730812395,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": "帮我找几张 明日方舟 白面鸮 的图片,渲染出来",
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730909927,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "assistant",
|
|
||||||
"content": "",
|
|
||||||
"tool_calls": [
|
|
||||||
{
|
|
||||||
"id": "call_ho74cop478w5gbfc0jnuo12f",
|
|
||||||
"index": 0,
|
|
||||||
"type": "function",
|
|
||||||
"function": {
|
|
||||||
"name": "image_crawler",
|
|
||||||
"arguments": "{\"key_word\":\"明日方舟 白面鸮\",\"image_num\":5}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730910906,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "tool",
|
|
||||||
"tool_call_id": "call_ho74cop478w5gbfc0jnuo12f",
|
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"text": "[ImageResult(url='https://c-ssl.duitang.com/uploads/item/201910/22/20191022190241_dixsc.thumb.1000_0.jpg', title='', source='bing'), ImageResult(url='https://img-baofun.zhhainiao.com/pcwallpaper_ugc_mobile/live/e06866505212ddcce0dabf9afebce225.mp4.jpg', title='', source='bing'), ImageResult(url='https://c-ssl.dtstatic.com/uploads/item/202007/15/20200715183732_iomsj.thumb.1000_0.jpg', title='', source='bing'), ImageResult(url='https://img-baofun.zhhainiao.com/pcwallpaper_ugc_mobile/live/710b67dfa125248f816d63617f551452_preview.jpg', title='', source='bing'), ImageResult(url='https://n.sinaimg.cn/sinacn10122/670/w400h270/20200104/db75-imrkkfx7540303.jpg', title='', source='bing')]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730911376,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "assistant",
|
|
||||||
"content": "以下是根据关键词“明日方舟 白面鸮”找到的图片:\n\n1. \n2. \n3. \n4. \n5. \n\n你可以点击链接查看这些图片。",
|
|
||||||
"extraInfo": {
|
|
||||||
"created": 1745730916072,
|
|
||||||
"state": "success",
|
|
||||||
"serverName": "Huoshan DeepSeek"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"modelIndex": 8,
|
|
||||||
"enableTools": [
|
|
||||||
{
|
|
||||||
"name": "image_crawler",
|
|
||||||
"description": "根据关键词从指定搜索引擎爬取图片",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"enableWebSearch": false,
|
|
||||||
"temperature": 0.7,
|
|
||||||
"contextLength": 10,
|
|
||||||
"systemPrompt": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"currentIndex": 0,
|
|
||||||
"tabs": [
|
|
||||||
{
|
|
||||||
"name": "Blank test 1",
|
|
||||||
"icon": "icon-blank",
|
|
||||||
"type": "blank",
|
|
||||||
"componentIndex": -1,
|
|
||||||
"storage": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"currentIndex": 0,
|
|
||||||
"tabs": [
|
|
||||||
{
|
|
||||||
"name": "资源",
|
|
||||||
"icon": "icon-file",
|
|
||||||
"type": "blank",
|
|
||||||
"componentIndex": 0,
|
|
||||||
"storage": {
|
|
||||||
"formData": {},
|
|
||||||
"currentType": "resource",
|
|
||||||
"currentResourceName": "network_log",
|
|
||||||
"lastResourceReadResponse": {
|
|
||||||
"contents": [
|
|
||||||
{
|
|
||||||
"uri": "network://log",
|
|
||||||
"mimeType": "text/plain",
|
|
||||||
"text": "Response from ..."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "工具",
|
|
||||||
"icon": "icon-tool",
|
|
||||||
"type": "blank",
|
|
||||||
"componentIndex": 2,
|
|
||||||
"storage": {
|
|
||||||
"formData": {
|
|
||||||
"a": 0,
|
|
||||||
"b": 0
|
|
||||||
},
|
|
||||||
"currentToolName": "add"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
const path = require('path');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
entry: './src/index.ts',
|
|
||||||
output: {
|
|
||||||
path: path.resolve(__dirname, 'dist'),
|
|
||||||
filename: 'bundle.js',
|
|
||||||
libraryTarget: 'commonjs2' // 使用 commonjs2 模块系统
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
extensions: ['.ts', '.js'],
|
|
||||||
fallback: {
|
|
||||||
bufferutil: false,
|
|
||||||
'utf-8-validate': false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.ts$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
use: 'ts-loader'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
target: 'node', // 指定目标环境为 Node.js
|
|
||||||
mode: 'production',
|
|
||||||
optimization: {
|
|
||||||
minimize: true
|
|
||||||
}
|
|
||||||
};
|
|
Loading…
x
Reference in New Issue
Block a user