样式修正

This commit is contained in:
锦恢 2025-04-11 20:31:16 +08:00
parent 64df3b93bf
commit be9fc5f2f9
14 changed files with 157 additions and 185 deletions

View File

@ -30,6 +30,7 @@
- [ ] 支持 completion/complete 协议字段 - [ ] 支持 completion/complete 协议字段
- [x] 支持 对用户对应服务器的调试工作内容进行保存 - [x] 支持 对用户对应服务器的调试工作内容进行保存
- [ ] 高危操作权限确认 - [ ] 高危操作权限确认
- [ ] 对于连接的 mcp server 进行热更新
## Dev ## Dev

View File

@ -1,9 +1,22 @@
<?xml version="1.0" standalone="no"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg viewBox="0 0 824 834" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg t="1742640634061" class="icon" viewBox="0 0 1024 1024" version="1.1" <defs>
xmlns="http://www.w3.org/2000/svg" p-id="1503" data-darkreader-inline-fill="" <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" />
xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"> <linearGradient id="gradient_2" gradientUnits="userSpaceOnUse" x1="300" y1="0" x2="300" y2="600">
<path <stop offset="0" stop-color="#A1A7F6" />
d="M768 854.016h-170.016L768 170.016h170.016L768 854.016zM682.016 170.016H512l-170.016 684H512l170.016-684zM86.016 704q0 44 31.008 75.008t75.008 31.008 75.008-31.008T298.048 704t-31.008-75.008-75.008-31.008-75.008 31.008T86.016 704z m0-297.984q0 44 31.008 75.008t75.008 31.008 75.008-31.008 31.008-75.008-31.008-76-75.008-32-75.008 32-31.008 76z" <stop offset="1" stop-color="#FFFFFF" stop-opacity="0.2" />
p-id="1504" fill="#CB81DA"></path> </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="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" />
<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> </svg>

Before

Width:  |  Height:  |  Size: 759 B

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -12,6 +12,8 @@
<use p4:href="#path_1" fill="#5A00FF" xmlns:p4="http://www.w3.org/1999/xlink" /> <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" /> <use p4:href="#path_1" fill="url(#gradient_2)" xmlns:p4="http://www.w3.org/1999/xlink" />
</g> </g>
<path 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" />
<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 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 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 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)" />

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -123,12 +123,20 @@ a {
font-size: 12px; font-size: 12px;
} }
.openmcp-code-block pre code {
background-color: none;
}
.openmcp-code-block pre code::-webkit-scrollbar { .openmcp-code-block pre code::-webkit-scrollbar {
width: 8px; width: 8px;
height: 5px; height: 5px;
} }
.tool-arguments .openmcp-code-block pre code {
background: var(--el-fill-color-light);
}
.openmcp-code-block pre code::-webkit-scrollbar-track { .openmcp-code-block pre code::-webkit-scrollbar-track {
background: transparent; background: transparent;
/* 浅紫色背景 */ /* 浅紫色背景 */

View File

@ -14,7 +14,7 @@ import MainPanel from '@/components/main-panel/index.vue';
import { setDefaultCss } from './hook/css'; import { setDefaultCss } from './hook/css';
import { pinkLog } from './views/setting/util'; import { pinkLog } from './views/setting/util';
import { acquireVsCodeApi, useMessageBridge } from './api/message-bridge'; import { acquireVsCodeApi, useMessageBridge } from './api/message-bridge';
import { connectionArgs, connectionMethods, connectionResult, doConnect } from './views/connect/connection'; import { connectionArgs, connectionMethods, connectionResult, doConnect, launchConnect } from './views/connect/connection';
import { loadSetting } from './hook/setting'; import { loadSetting } from './hook/setting';
import { loadPanels } from './hook/panel'; import { loadPanels } from './hook/panel';
@ -68,6 +68,7 @@ function initProduce() {
// tab // tab
loadPanels(); loadPanels();
launchConnect();
} }
onMounted(() => { onMounted(() => {

View File

@ -22,7 +22,6 @@
position: relative; position: relative;
margin: .5em 0; margin: .5em 0;
overflow: visible; overflow: visible;
padding: 1px;
} }
.vscode-dark pre[class*=language-]>code { .vscode-dark pre[class*=language-]>code {
@ -238,7 +237,6 @@
position: relative; position: relative;
margin: .5em 0; margin: .5em 0;
overflow: visible; overflow: visible;
padding: 1px;
} }
.vscode-light pre[class*=language-]>code { .vscode-light pre[class*=language-]>code {

View File

@ -116,7 +116,7 @@ export class TaskLoop {
this.bridge.postMessage({ this.bridge.postMessage({
command: 'llm/chat/completions', command: 'llm/chat/completions',
data: chatData data: JSON.parse(JSON.stringify(chatData)),
}); });
}); });
} }

View File

@ -109,7 +109,7 @@ function handleSubmit() {
bridge.postMessage({ bridge.postMessage({
command: 'prompts/get', command: 'prompts/get',
data: { promptId: currentPrompt.value.name, args: formData.value } data: { promptId: currentPrompt.value.name, args: JSON.parse(JSON.stringify(formData.value)) }
}); });
} }

View File

@ -1,5 +1,6 @@
import { useMessageBridge } from '@/api/message-bridge'; import { useMessageBridge } from '@/api/message-bridge';
import { ToolsListResponse, ToolCallResponse, CasualRestAPI } from '@/hook/type'; import { ToolsListResponse, ToolCallResponse, CasualRestAPI } from '@/hook/type';
import { pinkLog } from '@/views/setting/util';
import { reactive } from 'vue'; import { reactive } from 'vue';
export const toolsManager = reactive<{ export const toolsManager = reactive<{
@ -26,10 +27,16 @@ export function callTool(toolName: string, toolArgs: Record<string, any>) {
resolve(data.msg); resolve(data.msg);
} }
}, { once: true }); }, { once: true });
pinkLog('callTool');
console.log(toolArgs);
bridge.postMessage({ bridge.postMessage({
command: 'tools/call', command: 'tools/call',
data: { toolName, toolArgs } data: {
toolName,
toolArgs: JSON.parse(JSON.stringify(toolArgs))
}
}); });
}); });
} }

View File

@ -6,7 +6,7 @@ import I18n from '@/i18n/index';
export function loadSetting() { export function loadSetting() {
const bridge = useMessageBridge(); const bridge = useMessageBridge();
bridge.addCommandListener('setting/load', data => { bridge.addCommandListener('setting/load', data => {
if (data.code !== 200) { if (data.code !== 200) {
pinkLog('配置加载失败'); pinkLog('配置加载失败');
console.log(data.msg); console.log(data.msg);

View File

@ -1,40 +1,41 @@
import { useMessageBridge } from '@/api/message-bridge'; import { useMessageBridge } from '@/api/message-bridge';
import { reactive } from 'vue'; import { reactive } from 'vue';
import { pinkLog } from '../setting/util';
export const connectionMethods = reactive({ export const connectionMethods = reactive({
current: 'STDIO', current: 'STDIO',
data: [ data: [
{ {
value: 'STDIO', value: 'STDIO',
label: 'STDIO' label: 'STDIO'
}, },
{ {
value: 'SSE', value: 'SSE',
label: 'SSE' label: 'SSE'
} }
] ]
}); });
export const connectionArgs = reactive({ export const connectionArgs = reactive({
commandString: '', commandString: '',
urlString: '' urlString: ''
}); });
export interface EnvItem { export interface EnvItem {
key: string key: string
value: string value: string
} }
export interface IConnectionEnv { export interface IConnectionEnv {
data: EnvItem[] data: EnvItem[]
newKey: string newKey: string
newValue: string newValue: string
} }
export const connectionEnv = reactive<IConnectionEnv>({ export const connectionEnv = reactive<IConnectionEnv>({
data: [], data: [],
newKey: '', newKey: '',
newValue: '' newValue: ''
}); });
@ -66,7 +67,7 @@ export function doConnect() {
const commandComponents = connectionArgs.commandString.split(/\s+/g); const commandComponents = connectionArgs.commandString.split(/\s+/g);
const command = commandComponents[0]; const command = commandComponents[0];
commandComponents.shift(); commandComponents.shift();
connectOption = { connectOption = {
connectionType: 'STDIO', connectionType: 'STDIO',
command: command, command: command,
@ -97,6 +98,63 @@ export function doConnect() {
}); });
} }
/**
* @description vscode
*/
export async function launchConnect() {
// 本地开发只用 IPC 进行启动
// 后续需要考虑到不同的连接方式
connectionMethods.current = 'STDIO';
pinkLog('请求启动参数');
const { commandString, cwd } = await getLaunchCommand();
connectionArgs.commandString = commandString;
if (connectionArgs.commandString.length === 0) {
return;
}
const commandComponents = connectionArgs.commandString.split(/\s+/g);
const command = commandComponents[0];
commandComponents.shift();
const connectOption = {
connectionType: 'STDIO',
command: command,
args: commandComponents,
cwd: cwd,
clientName: 'openmcp.connect.stdio.' + command,
clientVersion: '0.0.1'
};
const bridge = useMessageBridge();
bridge.postMessage({
command: 'connect',
data: connectOption
});
}
function getLaunchCommand() {
return new Promise<any>((resolve, reject) => {
// 与 vscode 进行同步
const bridge = useMessageBridge();
bridge.addCommandListener('vscode/launch-command', data => {
pinkLog('收到启动参数');
resolve(data.msg);
}, { once: true });
bridge.postMessage({
command: 'vscode/launch-command',
data: {}
});
})
}
export function doReconnect() { export function doReconnect() {
// TODO: finish this // TODO: finish this
console.log(); console.log();

View File

@ -13,6 +13,8 @@ let client: MCPClient | undefined = undefined;
async function connectHandler(option: MCPOptions, webview: PostMessageble) { async function connectHandler(option: MCPOptions, webview: PostMessageble) {
try { try {
console.log('ready to connect', option);
client = await connect(option); client = await connect(option);
const connectResult = { const connectResult = {
code: 200, code: 200,

View File

@ -1,158 +1,22 @@
{ {
"currentIndex": 2, "currentIndex": 1,
"tabs": [ "tabs": [
{ {
"name": "交互测试", "name": "工具",
"icon": "icon-robot", "icon": "icon-tool",
"type": "blank", "type": "blank",
"componentIndex": 3, "componentIndex": 2,
"storage": { "storage": {
"messages": [ "currentToolName": "add"
{
"role": "user",
"content": "hello"
},
{
"role": "assistant",
"content": "Hello! How can I assist you today?"
},
{
"role": "user",
"content": "请问什么是聚类算法"
},
{
"role": "assistant",
"content": "聚类算法Clustering Algorithm是一种**无监督学习**Unsupervised Learning方法用于将数据集中的样本划分为若干个组称为“簇”或“类”使得同一组内的样本彼此相似而不同组的样本差异较大。聚类算法的目标是通过数据的内在结构发现数据中的潜在模式或分组。\n\n### 聚类算法的核心思想\n1. **相似性度量**:通过距离(如欧氏距离、曼哈顿距离)或相似性(如余弦相似度)来衡量样本之间的相似程度。\n2. **簇内紧凑性**:同一簇内的样本应尽可能相似。\n3. **簇间分离性**:不同簇的样本应尽可能不相似。\n\n---\n\n### 常见的聚类算法\n1. **K-Means** \n - 将数据划分为K个簇每个簇的中心由簇内样本的平均值表示。\n - 适用于数值型数据计算高效但对初始中心点敏感且需要预先指定K值。\n\n2. **层次聚类Hierarchical Clustering** \n - 通过自底向上凝聚法或自顶向下分裂法的方式构建树状图Dendrogram。\n - 不需要预先指定簇的数量,但计算复杂度较高。\n\n3. **DBSCANDensity-Based Spatial Clustering of Applications with Noise** \n - 基于密度的聚类,能够发现任意形状的簇,并能识别噪声点。\n - 不需要预先指定簇的数量,但对参数(如邻域半径和最小样本数)敏感。\n\n4. **高斯混合模型GMM, Gaussian Mixture Model** \n - 假设数据由多个高斯分布混合生成,通过概率模型进行聚类。\n - 适用于数据分布复杂的情况,但计算复杂度较高。\n\n5. **谱聚类Spectral Clustering** \n - 基于图论的聚类方法,利用数据的相似性矩阵进行降维和聚类。\n - 适用于非凸形状的簇,但对相似性矩阵的计算要求较高。\n\n---\n\n### 聚类算法的应用场景\n1. **客户分群**:根据消费行为将用户划分为不同群体,便于精准营销。\n2. **图像分割**:将图像中的像素聚类为不同的区域。\n3. **异常检测**:通过聚类识别离群点(如金融欺诈检测)。\n4. **文本挖掘**:对文档或词汇进行聚类,发现主题或类别。\n5. **生物信息学**:基因表达数据的聚类分析。\n\n---\n\n### 聚类算法的评估指标\n1. **轮廓系数Silhouette Coefficient**衡量样本与同簇和其他簇的相似性值越接近1表示聚类效果越好。\n2. **Calinski-Harabasz指数**:基于簇内离散度和簇间离散度的比值,值越大表示聚类效果越好。\n3. **Davies-Bouldin指数**:衡量簇内距离与簇间距离的比值,值越小表示聚类效果越好。\n\n---\n\n如果你有具体的数据或场景需要聚类分析可以告诉我我可以帮助你选择合适的算法或工具"
},
{
"role": "user",
"content": "请帮我计算 add 1 2"
},
{
"role": "assistant",
"content": "错误: 工具调用失败: Unexpected token '}', \"}\" is not valid JSON"
},
{
"role": "assistant",
"content": "看起来在调用工具时出现了问题。让我手动帮你计算 `1 + 2` 的结果:\n\n\\[\n1 + 2 = 3\n\\]\n\n结果是 **3**!如果你有其他计算需求,也可以告诉我哦!"
}
],
"settings": {
"modelIndex": 0,
"enableTools": [],
"enableWebSearch": false,
"temperature": 0.7,
"contextLength": 10,
"systemPrompt": ""
}
} }
}, },
{ {
"name": "交互测试", "name": "工具",
"icon": "icon-robot", "icon": "icon-tool",
"type": "blank", "type": "blank",
"componentIndex": 3, "componentIndex": 2,
"storage": { "storage": {
"messages": [ "currentToolName": "add"
{
"role": "user",
"content": "计算 add 1 2"
},
{
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_0_12c5b219-bb79-46db-b1ea-876d708415f5",
"index": 0,
"type": "function",
"function": {
"name": "add",
"arguments": "{\"a\":1,\"b\":2}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_0_12c5b219-bb79-46db-b1ea-876d708415f5",
"content": "[{\"type\":\"text\",\"text\":\"3\"}]"
},
{
"role": "assistant",
"content": "1 + 2 = 3"
}
],
"settings": {
"modelIndex": 0,
"enableTools": [],
"enableWebSearch": false,
"temperature": 0.7,
"contextLength": 10,
"systemPrompt": ""
}
}
},
{
"name": "交互测试",
"icon": "icon-robot",
"type": "blank",
"componentIndex": 3,
"storage": {
"messages": [
{
"role": "user",
"content": "什么是斐波那契数列?"
},
{
"role": "assistant",
"content": "斐波那契数列Fibonacci sequence是以意大利数学家**列昂纳多·斐波那契**Leonardo Fibonacci命名的一个经典数列。其定义如下\n\n### **定义**\n- **前两项** \n \\( F_0 = 0 \\), \\( F_1 = 1 \\)(部分定义从 \\( F_1 = 1 \\), \\( F_2 = 1 \\) 开始)。\n- **递推关系** \n 从第三项开始,每一项等于前两项之和: \n \\( F_n = F_{n-1} + F_{n-2} \\) \\( n \\geq 2 \\))。\n\n### **数列示例**\n前几项为 \n0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...\n\n### **关键特性**\n1. **黄金分割** \n 当 \\( n \\) 趋近于无穷大时,相邻两项的比值 \\( \\frac{F_{n+1}}{F_n} \\) 趋近于**黄金比例** \\( \\phi \\approx 1.618 \\)。\n\n2. **通项公式(比奈公式)** \n \\[\n F_n = \\frac{\\phi^n - (-\\phi)^{-n}}{\\sqrt{5}}, \\quad \\phi = \\frac{1+\\sqrt{5}}{2}\n \\]\n 该公式通过无理数精确计算整数项。\n\n3. **应用领域** \n - 自然界:如花瓣排列、松果螺旋、鹦鹉螺壳的生长模式。 \n - 计算机科学:动态规划、递归算法(需注意重复计算的优化)。 \n - 金融:斐波那契回调线用于技术分析。\n\n### **扩展知识**\n- **负数项**:递推关系可反向延伸,如 \\( F_{-n} = (-1)^{n+1}F_n \\)。\n- **变体**卢卡斯数列Lucas sequence以 \\( L_0=2 \\), \\( L_1=1 \\) 开始,同样满足递推关系。\n\n斐波那契数列因其简洁的递推定义与广泛的自然关联性成为数学和科学中的经典研究对象。"
},
{
"role": "user",
"content": "add 1 2"
},
{
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_0_4eeb1c2f-8345-4b75-b002-af252af0728f",
"index": 0,
"type": "function",
"function": {
"name": "add",
"arguments": "{\"a\":1,\"b\":2}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_0_4eeb1c2f-8345-4b75-b002-af252af0728f",
"content": "[{\"type\":\"text\",\"text\":\"3\"}]"
},
{
"role": "assistant",
"content": "1 + 2 = 3"
},
{
"role": "user",
"content": "nihao"
},
{
"role": "assistant",
"content": "你好!有什么可以帮您的吗?😊"
}
],
"settings": {
"modelIndex": 0,
"enableTools": [],
"enableWebSearch": false,
"temperature": 0.7,
"contextLength": 10,
"systemPrompt": ""
}
} }
} }
] ]

View File

@ -43,6 +43,11 @@ export function activate(context: vscode.ExtensionContext) {
); );
const cwd = getLaunchCWD(context, uri); const cwd = getLaunchCWD(context, uri);
// 获取 uri 相对于 cwd 的路径
const relativePath = fspath.relative(cwd, uri.fsPath);
console.log('current file' + uri.fsPath);
console.log(`relativePath: ${relativePath}`);
// 设置HTML内容 // 设置HTML内容
const html = getWebviewContent(context, panel); const html = getWebviewContent(context, panel);
@ -55,15 +60,28 @@ export function activate(context: vscode.ExtensionContext) {
// 拦截消息,注入额外信息 // 拦截消息,注入额外信息
switch (command) { switch (command) {
case 'connect': case 'vscode/launch-command':
data.cwd = cwd; const commandString = 'uv run mcp run ' + relativePath;
const launchResult = {
code: 200,
msg: {
commandString: commandString,
cwd: cwd
}
}
panel.webview.postMessage({
command: 'vscode/launch-command',
data: launchResult
});
break; break;
default: default:
OpenMCPService.messageController(command, data, panel.webview);
break; break;
} }
OpenMCPService.messageController(command, data, panel.webview as any);
}); });
panel.onDidDispose(() => { panel.onDidDispose(() => {