diff --git a/media/webview/script.js b/media/webview/script.js index a3c48f0..2a28b44 100644 --- a/media/webview/script.js +++ b/media/webview/script.js @@ -41,12 +41,17 @@ document.addEventListener('DOMContentLoaded', () => { return; } + // 获取深度思考开关状态 + const deepThinkingCheckbox = document.getElementById('deep-thinking-checkbox'); + const enableDeepThinking = deepThinkingCheckbox ? deepThinkingCheckbox.checked : false; + // 发送消息 vscode.postMessage({ command: 'ask', text, fileContent: selectedCodeForContext, - fileContentPath: contextFilePath // 添加文件路径 + fileContentPath: contextFilePath, // 添加文件路径 + enableDeepThinking: enableDeepThinking // 添加深度思考标志 }); // 切换按钮为停止按钮 diff --git a/media/webview/style.css b/media/webview/style.css index ca32615..cf2cb30 100644 --- a/media/webview/style.css +++ b/media/webview/style.css @@ -64,46 +64,62 @@ code { /* 表单区域 */ #chat-form { - display: flex; - gap: 10px; margin-top: auto; padding: 10px 0; } +.input-container { + display: flex; + align-items: center; + gap: 10px; + padding: 8px; + background-color: var(--vscode-input-background); + border: 1px solid var(--vscode-dropdown-border); + border-radius: 6px; + transition: border-color 0.2s; +} + +.input-container:focus-within { + border-color: var(--vscode-focusBorder); + box-shadow: 0 0 0 1px var(--vscode-focusBorder); +} + #user-input { flex: 1; - padding: 8px 12px; - border: 1px solid var(--vscode-dropdown-border); - border-radius: 4px; - background-color: var(--vscode-input-background); + padding: 6px 8px; + border: none; + background-color: transparent; color: var(--vscode-input-foreground); font-family: var(--vscode-font-family); font-size: var(--vscode-font-size); + outline: none; } -#user-input:focus { - outline: none; - border-color: var(--vscode-focusBorder); +#user-input::placeholder { + color: var(--vscode-input-placeholderForeground); } #chat-form button { - padding: 8px 16px; - background-color: #007acc; - color: white; + padding: 6px 16px; + background-color: var(--vscode-button-background); + color: var(--vscode-button-foreground); border: none; border-radius: 4px; cursor: pointer; - font-size: 14px; + font-size: 13px; + font-weight: 500; transition: background-color 0.2s; + white-space: nowrap; } #chat-form button:hover { - background-color: #005a9e; + background-color: var(--vscode-button-hoverBackground); } /* 停止按钮样式 */ #chat-form button.stop-button { background-color: #f44336; + color: white; } #chat-form button.stop-button:hover { @@ -501,3 +517,33 @@ code { color: var(--vscode-descriptionForeground); font-size: 12px; } + +/* 深度思考开关样式 */ +.deep-thinking-toggle { + display: flex; + align-items: center; + gap: 6px; + cursor: pointer; + font-size: 12px; + white-space: nowrap; + user-select: none; + padding: 4px 8px; + border-radius: 4px; + transition: background-color 0.2s; +} + +.deep-thinking-toggle:hover { + background-color: var(--vscode-list-hoverBackground); +} + +.deep-thinking-toggle input[type="checkbox"] { + cursor: pointer; + width: 14px; + height: 14px; + margin: 0; +} + +.deep-thinking-toggle .toggle-label { + color: var(--vscode-foreground); + font-weight: 500; +} diff --git a/src/MessageHandler.ts b/src/MessageHandler.ts index bdf9d8d..95514a0 100644 --- a/src/MessageHandler.ts +++ b/src/MessageHandler.ts @@ -74,13 +74,14 @@ export class MessageHandler { const fileContent = message.fileContent; const fileName = message.fileContentPath ? path.basename(message.fileContentPath) : "current_file.txt"; const history = currentSessionHistory; + const enableDeepThinking = message.enableDeepThinking || false; currentSessionHistory = [...history, {role: 'user', content: question}]; this.provider._postMessage({command: 'addMessage', role: 'user', content: question}); try { - const response = await callQwenAPI(question, history, fileContent, this.context, fileName); + const response = await callQwenAPI(question, history, fileContent, this.context, fileName, enableDeepThinking); // 发送开始流式传输的消息 this.provider._postMessage({command: 'startStream', role: 'assistant'}); @@ -98,7 +99,7 @@ export class MessageHandler { if (done) break; const chunk = decoder.decode(value, {stream: true}); - + console.log("chunk:",chunk) // 检查是否包含event: end事件 let processedChunk = chunk; if (chunk.includes('event: end')) { diff --git a/src/utils/modelApi.ts b/src/utils/modelApi.ts index 9574d62..0469abe 100644 --- a/src/utils/modelApi.ts +++ b/src/utils/modelApi.ts @@ -2,69 +2,74 @@ import vscode from "vscode"; import path from "path"; // 获取API配置的函数 -function getApiConfig(context: vscode.ExtensionContext) { - // 从用户配置中获取设置 - const config = vscode.workspace.getConfiguration('ai-chat.api'); - const userUrl = config.get('url'); - const userBaseUrl = config.get('baseUrl'); - const userApiKey = config.get('key'); - - // 如果用户配置了完整URL,优先使用 - if (userUrl) { - return { - url: userUrl, - apiKey: userApiKey || 'dev-token' - }; - } - - // 如果用户配置了基础URL,使用基础URL加上默认路径 - if (userBaseUrl) { - return { - url: `${userBaseUrl}/comp/api/v1/chat/completions-stream`, - apiKey: userApiKey || 'dev-token' - }; - } - - // 检测code-server环境 - const codeServerUrl = process.env.CODE_SERVER_URL; - if (codeServerUrl) { - // 在code-server环境中,尝试使用相对路径或者基于当前地址的API地址 - try { - const baseUrl = new URL(codeServerUrl); - return { - url: `${baseUrl.origin}/comp/api/v1/chat/completions-stream`, - apiKey: userApiKey || 'dev-token' - }; - } catch (e) { - // 如果解析失败,使用默认地址 +function getApiConfig(context: vscode.ExtensionContext, enableDeepThinking: boolean = false) { + // 从用户配置中获取设置 + const config = vscode.workspace.getConfiguration('ai-chat.api'); + const userUrl = config.get('url'); + const userBaseUrl = config.get('baseUrl'); + const userApiKey = config.get('key'); + + // 根据是否启用深度思考选择不同的端点 + const endpoint = enableDeepThinking + ? '/comp/api/v1/chat/completions-stream-cot' + : '/comp/api/v1/chat/completions-stream'; + + // 如果用户配置了完整URL,优先使用 + if (userUrl) { + return { + url: userUrl, + apiKey: userApiKey || 'dev-token' + }; } - } - - // 检查CODE_SERVER_CONFIG环境变量 - const codeServerConfig = process.env.CODE_SERVER_CONFIG; - if (codeServerConfig) { - try { - // 尝试从配置中解析bindAddr - const configObj = JSON.parse(codeServerConfig); - if (configObj.bindAddr) { - const [host, port] = configObj.bindAddr.split(':'); - if (host && port) { - return { - url: `http://${host}:${port}/comp/api/v1/chat/completions-stream`, + + // 如果用户配置了基础URL,使用基础URL加上对应端点 + if (userBaseUrl) { + return { + url: `${userBaseUrl}${endpoint}`, apiKey: userApiKey || 'dev-token' - }; + }; + } + + // 检测code-server环境 + const codeServerUrl = process.env.CODE_SERVER_URL; + if (codeServerUrl) { + // 在code-server环境中,尝试使用相对路径或者基于当前地址的API地址 + try { + const baseUrl = new URL(codeServerUrl); + return { + url: `${baseUrl.origin}${endpoint}`, + apiKey: userApiKey || 'dev-token' + }; + } catch (e) { + // 如果解析失败,使用默认地址 } - } - } catch (e) { - // 解析失败则继续使用默认配置 } - } - - // 默认配置 - return { - url: 'https://p13-ai.ngsk.tech:7001/comp/api/v1/chat/completions-stream', - apiKey: userApiKey || 'dev-token' - }; + + // 检查CODE_SERVER_CONFIG环境变量 + const codeServerConfig = process.env.CODE_SERVER_CONFIG; + if (codeServerConfig) { + try { + // 尝试从配置中解析bindAddr + const configObj = JSON.parse(codeServerConfig); + if (configObj.bindAddr) { + const [host, port] = configObj.bindAddr.split(':'); + if (host && port) { + return { + url: `http://${host}:${port}${endpoint}`, + apiKey: userApiKey || 'dev-token' + }; + } + } + } catch (e) { + // 解析失败则继续使用默认配置 + } + } + + // 默认配置 + return { + url: `https://p13-ai.ngsk.tech:7001${endpoint}`, + apiKey: userApiKey || 'dev-token' + }; } export async function callQwenAPI( @@ -72,9 +77,10 @@ export async function callQwenAPI( history: any[], fileContent: string, context: vscode.ExtensionContext, - filename: string = "" + filename: string = "", + enableDeepThinking: boolean = false ): Promise { - const { url, apiKey } = getApiConfig(context); + const {url, apiKey} = getApiConfig(context, enableDeepThinking); const messages = [ { @@ -91,6 +97,21 @@ export async function callQwenAPI( console.log("messages:", messages) try { + const requestBody: any = { + model: 'Qwen2_5_Coder', + messages, + context_file: { + filename: filename, + section_type: "code", + content: fileContent + } + }; + + // 如果启用深度思考,添加 enable_cot 参数 + if (enableDeepThinking) { + requestBody.enable_cot = true; + } + const params = { method: 'POST', headers: { @@ -98,15 +119,7 @@ export async function callQwenAPI( 'Content-Type': 'application/json', // 'Accept': 'text/event-stream' }, - body: JSON.stringify({ - model: 'Qwen2_5_Coder', - messages, - context_file: { - filename: filename, - section_type: "code", - content: fileContent - } - }) + body: JSON.stringify(requestBody) } console.log("params:", JSON.stringify(params)) diff --git a/src/utils/webView.ts b/src/utils/webView.ts index 3c34286..c352aa6 100644 --- a/src/utils/webView.ts +++ b/src/utils/webView.ts @@ -75,8 +75,14 @@ export function getWebviewContent(styleUri: vscode.Uri, scriptUri: vscode.Uri,hi
- - +
+ + + +