增加 task-loop 的打包

This commit is contained in:
锦恢 2025-05-09 23:55:34 +08:00
parent 68f45fedf7
commit 1fef3a1150
6 changed files with 558 additions and 6 deletions

154
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "openmcp", "name": "openmcp",
"version": "0.0.6", "version": "0.0.8",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "openmcp", "name": "openmcp",
"version": "0.0.6", "version": "0.0.8",
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2", "@modelcontextprotocol/sdk": "^1.10.2",
"@seald-io/nedb": "^4.1.1", "@seald-io/nedb": "^4.1.1",
@ -24,6 +24,7 @@
"@types/showdown": "^2.0.0", "@types/showdown": "^2.0.0",
"@types/vscode": "^1.72.0", "@types/vscode": "^1.72.0",
"copy-webpack-plugin": "^13.0.0", "copy-webpack-plugin": "^13.0.0",
"null-loader": "^4.0.1",
"ts-loader": "^9.5.1", "ts-loader": "^9.5.1",
"typescript": "^5.4.2", "typescript": "^5.4.2",
"webpack": "^5.99.5", "webpack": "^5.99.5",
@ -570,6 +571,16 @@
"proxy-from-env": "^1.1.0" "proxy-from-env": "^1.1.0"
} }
}, },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/bmp-js": { "node_modules/bmp-js": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
@ -980,6 +991,16 @@
"integrity": "sha512-kL4+wUTD7RSA5FHx5YwWtjDnEEkIIikFgWHR4P6fqjw1PPLlqYkxeOb++wAauAssat0YClCy8Y3C5SxgSkjibQ==", "integrity": "sha512-kL4+wUTD7RSA5FHx5YwWtjDnEEkIIikFgWHR4P6fqjw1PPLlqYkxeOb++wAauAssat0YClCy8Y3C5SxgSkjibQ==",
"dev": true "dev": true
}, },
"node_modules/emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/encodeurl": { "node_modules/encodeurl": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@ -1266,6 +1287,13 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true "dev": true
}, },
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-uri": { "node_modules/fast-uri": {
"version": "3.0.6", "version": "3.0.6",
"resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.0.6.tgz", "resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.0.6.tgz",
@ -1870,6 +1898,19 @@
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true "dev": true
}, },
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/kind-of": { "node_modules/kind-of": {
"version": "6.0.3", "version": "6.0.3",
"resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz",
@ -1897,6 +1938,21 @@
"node": ">=6.11.5" "node": ">=6.11.5"
} }
}, },
"node_modules/loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"license": "MIT",
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"engines": {
"node": ">=8.9.0"
}
},
"node_modules/localforage": { "node_modules/localforage": {
"version": "1.10.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
@ -2064,6 +2120,80 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/null-loader": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz",
"integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==",
"dev": true,
"license": "MIT",
"dependencies": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
}
},
"node_modules/null-loader/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/null-loader/node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"ajv": "^6.9.1"
}
},
"node_modules/null-loader/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true,
"license": "MIT"
},
"node_modules/null-loader/node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/object-assign": { "node_modules/object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -2305,6 +2435,16 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/qs": { "node_modules/qs": {
"version": "6.14.0", "version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
@ -3037,6 +3177,16 @@
"browserslist": ">= 4.21.0" "browserslist": ">= 4.21.0"
} }
}, },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
}
},
"node_modules/util": { "node_modules/util": {
"version": "0.12.5", "version": "0.12.5",
"resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",

View File

@ -219,7 +219,8 @@
"pretest": "npm run compile && npm run lint", "pretest": "npm run compile && npm run lint",
"lint": "eslint src --ext ts", "lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js", "test": "node ./out/test/runTest.js",
"prepare:ocr": "webpack --config webpack/webpack.tesseract.js" "prepare:ocr": "webpack --config webpack/webpack.tesseract.js",
"build:task-loop": "webpack --config webpack/webpack.task-loop.js"
}, },
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2", "@modelcontextprotocol/sdk": "^1.10.2",
@ -238,6 +239,7 @@
"@types/showdown": "^2.0.0", "@types/showdown": "^2.0.0",
"@types/vscode": "^1.72.0", "@types/vscode": "^1.72.0",
"copy-webpack-plugin": "^13.0.0", "copy-webpack-plugin": "^13.0.0",
"null-loader": "^4.0.1",
"ts-loader": "^9.5.1", "ts-loader": "^9.5.1",
"typescript": "^5.4.2", "typescript": "^5.4.2",
"webpack": "^5.99.5", "webpack": "^5.99.5",

View File

@ -1,4 +1,4 @@
import { ToolCallContent, ToolItem } from "@/hook/type"; import type { ToolCallContent, ToolItem } from "@/hook/type";
import { Ref, ref } from "vue"; import { Ref, ref } from "vue";
import type { OpenAI } from 'openai'; import type { OpenAI } from 'openai';

View File

@ -0,0 +1,357 @@
/* eslint-disable */
import type { Ref } from "vue";
import { ToolCall, ChatStorage, getToolSchema, MessageState } from "../chat-box/chat";
import { useMessageBridge } from "@/api/message-bridge";
import type { OpenAI } from 'openai';
import { llmManager, llms } from "@/views/setting/llm";
import { pinkLog, redLog } from "@/views/setting/util";
import { ElMessage } from "element-plus";
import { handleToolCalls } from "./handle-tool-calls";
export type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk;
export type ChatCompletionCreateParamsBase = OpenAI.Chat.Completions.ChatCompletionCreateParams & { id?: string };
interface TaskLoopOptions {
maxEpochs: number;
maxJsonParseRetry: number;
}
interface IErrorMssage {
state: MessageState,
msg: string
}
interface IDoConversationResult {
stop: boolean;
}
/**
* @description
*/
export class TaskLoop {
private bridge = useMessageBridge();
private currentChatId = '';
private completionUsage: ChatCompletionChunk['usage'] | undefined;
constructor(
private readonly streamingContent: Ref<string>,
private readonly streamingToolCalls: Ref<ToolCall[]>,
private onError: (error: IErrorMssage) => void = (msg) => {},
private onChunk: (chunk: ChatCompletionChunk) => void = (chunk) => {},
private onDone: () => void = () => {},
private onEpoch: () => void = () => {},
private readonly taskOptions: TaskLoopOptions = { maxEpochs: 20, maxJsonParseRetry: 3 },
) {
}
private handleChunkDeltaContent(chunk: ChatCompletionChunk) {
const content = chunk.choices[0]?.delta?.content || '';
if (content) {
this.streamingContent.value += content;
}
}
private handleChunkDeltaToolCalls(chunk: ChatCompletionChunk) {
const toolCall = chunk.choices[0]?.delta?.tool_calls?.[0];
if (toolCall) {
const currentCall = this.streamingToolCalls.value[toolCall.index];
if (currentCall === undefined) {
// 新的工具调用开始
this.streamingToolCalls.value[toolCall.index] = {
id: toolCall.id,
index: toolCall.index,
type: 'function',
function: {
name: toolCall.function?.name || '',
arguments: toolCall.function?.arguments || ''
}
};
} else {
// 累积现有工具调用的信息
if (currentCall) {
if (toolCall.id) {
currentCall.id = toolCall.id;
}
if (toolCall.function?.name) {
currentCall.function.name = toolCall.function.name;
}
if (toolCall.function?.arguments) {
currentCall.function.arguments += toolCall.function.arguments;
}
}
}
}
}
private handleChunkUsage(chunk: ChatCompletionChunk) {
const usage = chunk.usage;
if (usage) {
this.completionUsage = usage;
}
}
private doConversation(chatData: ChatCompletionCreateParamsBase) {
return new Promise<IDoConversationResult>((resolve, reject) => {
const chunkHandler = this.bridge.addCommandListener('llm/chat/completions/chunk', data => {
// data.code 一定为 200否则不会走这个 route
const { chunk } = data.msg as { chunk: ChatCompletionChunk };
// 处理增量的 content 和 tool_calls
this.handleChunkDeltaContent(chunk);
this.handleChunkDeltaToolCalls(chunk);
this.handleChunkUsage(chunk);
this.onChunk(chunk);
}, { once: false });
const doneHandler = this.bridge.addCommandListener('llm/chat/completions/done', data => {
this.onDone();
chunkHandler();
errorHandler();
resolve({
stop: false
});
}, { once: true });
const errorHandler = this.bridge.addCommandListener('llm/chat/completions/error', data => {
this.onError({
state: MessageState.ReceiveChunkError,
msg: data.msg || '请求模型服务时发生错误'
});
chunkHandler();
doneHandler();
resolve({
stop: true
});
}, { once: true });
console.log(chatData);
this.bridge.postMessage({
command: 'llm/chat/completions',
data: JSON.parse(JSON.stringify(chatData)),
});
});
}
public makeChatData(tabStorage: ChatStorage): ChatCompletionCreateParamsBase | undefined {
const baseURL = llms[llmManager.currentModelIndex].baseUrl;
const apiKey = llms[llmManager.currentModelIndex].userToken || '';
if (apiKey.trim() === '') {
if (tabStorage.messages.length > 0 && tabStorage.messages[tabStorage.messages.length - 1].role === 'user') {
tabStorage.messages.pop();
ElMessage.error('请先设置 API Key');
}
return undefined;
}
const model = llms[llmManager.currentModelIndex].userModel;
const temperature = tabStorage.settings.temperature;
const tools = getToolSchema(tabStorage.settings.enableTools);
const userMessages = [];
if (tabStorage.settings.systemPrompt) {
userMessages.push({
role: 'system',
content: tabStorage.settings.systemPrompt
});
}
// 如果超出了 tabStorage.settings.contextLength, 则删除最早的消息
const loadMessages = tabStorage.messages.slice(- tabStorage.settings.contextLength);
userMessages.push(...loadMessages);
// 增加一个id用于锁定状态
const id = crypto.randomUUID();
const chatData = {
id,
baseURL,
apiKey,
model,
temperature,
tools,
messages: userMessages,
} as ChatCompletionCreateParamsBase;
return chatData;
}
public abort() {
this.bridge.postMessage({
command: 'llm/chat/completions/abort',
data: {
id: this.currentChatId
}
});
this.streamingContent.value = '';
this.streamingToolCalls.value = [];
}
public registerOnError(handler: (msg: IErrorMssage) => void) {
this.onError = handler;
}
public registerOnChunk(handler: (chunk: ChatCompletionChunk) => void) {
this.onChunk = handler;
}
public registerOnDone(handler: () => void) {
this.onDone = handler;
}
public registerOnEpoch(handler: () => void) {
this.onEpoch = handler;
}
public setMaxEpochs(maxEpochs: number) {
this.taskOptions.maxEpochs = maxEpochs;
}
/**
* @description DOM
*/
public async start(tabStorage: ChatStorage, userMessage: string) {
// 添加目前的消息
tabStorage.messages.push({
role: 'user',
content: userMessage,
extraInfo: {
created: Date.now(),
state: MessageState.Success,
serverName: llms[llmManager.currentModelIndex].id || 'unknown'
}
});
let jsonParseErrorRetryCount = 0;
for (let i = 0; i < this.taskOptions.maxEpochs; ++ i) {
this.onEpoch();
// 初始累计清空
this.streamingContent.value = '';
this.streamingToolCalls.value = [];
this.completionUsage = undefined;
// 构造 chatData
const chatData = this.makeChatData(tabStorage);
if (!chatData) {
this.onDone();
break;
}
this.currentChatId = chatData.id!;
// 发送请求
const doConverationResult = await this.doConversation(chatData);
console.log(doConverationResult);
// 如果存在需要调度的工具
if (this.streamingToolCalls.value.length > 0) {
tabStorage.messages.push({
role: 'assistant',
content: this.streamingContent.value || '',
tool_calls: this.streamingToolCalls.value,
extraInfo: {
created: Date.now(),
state: MessageState.Success,
serverName: llms[llmManager.currentModelIndex].id || 'unknown'
}
});
pinkLog('调用工具数量:' + this.streamingToolCalls.value.length);
for (const toolCall of this.streamingToolCalls.value || []) {
const toolCallResult = await handleToolCalls(toolCall);
if (toolCallResult.state === MessageState.ParseJsonError) {
// 如果是因为解析 JSON 错误,则重新开始
tabStorage.messages.pop();
jsonParseErrorRetryCount ++;
redLog('解析 JSON 错误 ' + toolCall?.function?.arguments);
// 如果因为 JSON 错误而失败太多,就只能中断了
if (jsonParseErrorRetryCount >= this.taskOptions.maxJsonParseRetry) {
tabStorage.messages.push({
role: 'assistant',
content: `解析 JSON 错误,无法继续调用工具 (累计错误次数 ${this.taskOptions.maxJsonParseRetry})`,
extraInfo: {
created: Date.now(),
state: toolCallResult.state,
serverName: llms[llmManager.currentModelIndex].id || 'unknown',
usage: undefined
}
});
break;
}
} else if (toolCallResult.state === MessageState.Success) {
tabStorage.messages.push({
role: 'tool',
index: toolCall.index || 0,
tool_call_id: toolCall.id || toolCall.function.name,
content: toolCallResult.content,
extraInfo: {
created: Date.now(),
state: toolCallResult.state,
serverName: llms[llmManager.currentModelIndex].id || 'unknown',
usage: this.completionUsage
}
});
} else if (toolCallResult.state === MessageState.ToolCall) {
tabStorage.messages.push({
role: 'tool',
index: toolCall.index || 0,
tool_call_id: toolCall.id || toolCall.function.name,
content: toolCallResult.content,
extraInfo: {
created: Date.now(),
state: toolCallResult.state,
serverName: llms[llmManager.currentModelIndex].id || 'unknown',
usage: this.completionUsage
}
});
}
}
} else if (this.streamingContent.value) {
tabStorage.messages.push({
role: 'assistant',
content: this.streamingContent.value,
extraInfo: {
created: Date.now(),
state: MessageState.Success,
serverName: llms[llmManager.currentModelIndex].id || 'unknown',
usage: this.completionUsage
}
});
break;
} else {
// 一些提示
break;
}
// 回答聚合完成后根据 stop 来决定是否提前中断
if (doConverationResult.stop) {
break;
}
}
}
}

View File

@ -1,9 +1,8 @@
/* eslint-disable */ /* eslint-disable */
import { Ref } from "vue"; import type { Ref } from "vue";
import { ToolCall, ChatStorage, getToolSchema, MessageState } from "../chat-box/chat"; import { ToolCall, ChatStorage, getToolSchema, MessageState } from "../chat-box/chat";
import { useMessageBridge } from "@/api/message-bridge"; import { useMessageBridge } from "@/api/message-bridge";
import type { OpenAI } from 'openai'; import type { OpenAI } from 'openai';
import { callTool } from "../../tool/tools";
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";

View File

@ -0,0 +1,44 @@
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'production',
entry: './renderer/src/components/main-panel/chat/core/task-loop-sdk.ts',
output: {
path: path.resolve(__dirname, '../openmcp-sdk'),
filename: 'task-loop-sdk.js',
libraryTarget: 'commonjs2'
},
target: 'node',
resolve: {
extensions: ['.ts', '.js'],
alias: {
'@': path.resolve(__dirname, '../renderer/src'), // 修正路径别名
},
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.vue$/,
use: {
loader: 'null-loader'
}
}
],
},
optimization: {
minimizer: [
new TerserPlugin({
extractComments: false, // 禁用提取许可证文件
}),
],
},
externals: {
vue: 'vue', // 不打包 vue 库
},
};