From beaf4f5ba1dbf562cc731064aa61f0b5ada8c30f Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Sat, 26 Apr 2025 17:03:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=B8=AD=E9=97=B4=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- renderer/public/iconfont.css | 18 ++- renderer/public/iconfont.woff2 | Bin 5316 -> 5640 bytes .../src/components/k-cute-textarea/index.vue | 70 ++++++++++ .../src/components/main-panel/chat/chat.ts | 3 +- .../src/components/main-panel/chat/index.vue | 45 +++---- .../main-panel/chat/message/assistant.vue | 4 + .../main-panel/chat/message/streaming-box.vue | 4 + .../main-panel/chat/message/toolcall.vue | 4 + .../main-panel/chat/message/user.vue | 124 +++++++++++++++++- service/src/controller/index.ts | 2 +- service/src/service/llm.ts | 20 +-- 11 files changed, 252 insertions(+), 42 deletions(-) create mode 100644 renderer/src/components/k-cute-textarea/index.vue diff --git a/renderer/public/iconfont.css b/renderer/public/iconfont.css index 185d496..38d4f03 100644 --- a/renderer/public/iconfont.css +++ b/renderer/public/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 4870215 */ - src: url('iconfont.woff2?t=1745313248329') format('woff2'), - url('iconfont.woff?t=1745313248329') format('woff'), - url('iconfont.ttf?t=1745313248329') format('truetype'); + src: url('iconfont.woff2?t=1745654620708') format('woff2'), + url('iconfont.woff?t=1745654620708') format('woff'), + url('iconfont.ttf?t=1745654620708') format('truetype'); } .iconfont { @@ -13,6 +13,18 @@ -moz-osx-font-smoothing: grayscale; } +.icon-copy:before { + content: "\e77c"; +} + +.icon-restart:before { + content: "\e86b"; +} + +.icon-edit2:before { + content: "\e848"; +} + .icon-star:before { content: "\e80f"; } diff --git a/renderer/public/iconfont.woff2 b/renderer/public/iconfont.woff2 index 2da98f838e1202c4301aa580afad9f8fe30cb317..6a0068afbdad0632e0319ad6d1bdc2389c173093 100644 GIT binary patch literal 5640 zcmV+j7We6QPew8T0RR9102T-U3jhEB04L-C02R3a0RR9100000000000000000000 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 diff --git a/renderer/src/components/k-cute-textarea/index.vue b/renderer/src/components/k-cute-textarea/index.vue new file mode 100644 index 0000000..583fb4d --- /dev/null +++ b/renderer/src/components/k-cute-textarea/index.vue @@ -0,0 +1,70 @@ + + + \ No newline at end of file diff --git a/renderer/src/components/main-panel/chat/chat.ts b/renderer/src/components/main-panel/chat/chat.ts index 7603708..1d107e9 100644 --- a/renderer/src/components/main-panel/chat/chat.ts +++ b/renderer/src/components/main-panel/chat/chat.ts @@ -103,4 +103,5 @@ export function getToolSchema(enableTools: EnableToolItem[]) { } } return toolsSchema; -} \ No newline at end of file +} + diff --git a/renderer/src/components/main-panel/chat/index.vue b/renderer/src/components/main-panel/chat/index.vue index f615b1c..6c54428 100644 --- a/renderer/src/components/main-panel/chat/index.vue +++ b/renderer/src/components/main-panel/chat/index.vue @@ -14,23 +14,23 @@
- +
- +
- +
- +
@@ -52,8 +52,12 @@
- + @@ -77,6 +81,9 @@ import { llmManager, llms } from '@/views/setting/llm'; import * as Message from './message'; import Setting from './setting.vue'; +import KCuteTextarea from '@/components/k-cute-textarea/index.vue'; + +import { provide } from 'vue'; defineComponent({ name: 'chat' }); @@ -93,10 +100,6 @@ const tab = tabs.content[props.tabId]; const tabStorage = tab.storage as ChatStorage; const userInput = ref(''); -const inputHeightLines = computed(() => { - const currentLines = userInput.value.split('\n').length; - return Math.min(12, Math.max(5, currentLines)); -}); // 创建 messages if (!tabStorage.messages) { @@ -165,14 +168,6 @@ const updateScrollHeight = () => { } }; -const handleKeydown = (event: KeyboardEvent) => { - if (event.key === 'Enter' && !event.shiftKey) { - event.preventDefault(); - handleSend(); - } - // Shift+Enter 允许自然换行 -}; - const autoScroll = ref(true); const scrollbarRef = ref(); @@ -218,14 +213,13 @@ watch(streamingToolCalls, () => { let loop: TaskLoop | undefined = undefined; -const handleSend = () => { - if (!userInput.value.trim() || isLoading.value) return; +const handleSend = (newMessage?: string) => { + const userMessage = newMessage || userInput.value.trim(); + if (!userMessage || isLoading.value) return; autoScroll.value = true; isLoading.value = true; - const userMessage = userInput.value.trim(); - loop = new TaskLoop(streamingContent, streamingToolCalls); loop.registerOnError((error) => { @@ -278,6 +272,8 @@ const handleAbort = () => { } }; +provide('handleSend', handleSend); + onMounted(() => { updateScrollHeight(); window.addEventListener('resize', updateScrollHeight); @@ -357,9 +353,10 @@ onUnmounted(() => { .user .message-text { margin-top: 10px; margin-bottom: 10px; + width: 100%; } -.user .message-text>span { +.user .message-text > span { border-radius: .9em; background-color: var(--main-light-color); padding: 10px 15px; @@ -419,7 +416,7 @@ onUnmounted(() => { height: auto; padding: 8px 12px; font-size: 20px; - border-radius: .5em; + border-radius: 1.2em !important; } :deep(.chat-settings) { diff --git a/renderer/src/components/main-panel/chat/message/assistant.vue b/renderer/src/components/main-panel/chat/message/assistant.vue index 06c24fe..ef7d5e1 100644 --- a/renderer/src/components/main-panel/chat/message/assistant.vue +++ b/renderer/src/components/main-panel/chat/message/assistant.vue @@ -16,6 +16,10 @@ const props = defineProps({ message: { type: Object, required: true + }, + tabId: { + type: Number, + required: true } }); diff --git a/renderer/src/components/main-panel/chat/message/streaming-box.vue b/renderer/src/components/main-panel/chat/message/streaming-box.vue index a49fb36..ccacad5 100644 --- a/renderer/src/components/main-panel/chat/message/streaming-box.vue +++ b/renderer/src/components/main-panel/chat/message/streaming-box.vue @@ -25,6 +25,10 @@ const props = defineProps({ streamingContent: { type: String, required: true + }, + tabId: { + type: Number, + required: true } }); diff --git a/renderer/src/components/main-panel/chat/message/toolcall.vue b/renderer/src/components/main-panel/chat/message/toolcall.vue index 037c4bb..4ce3517 100644 --- a/renderer/src/components/main-panel/chat/message/toolcall.vue +++ b/renderer/src/components/main-panel/chat/message/toolcall.vue @@ -104,6 +104,10 @@ const props = defineProps({ message: { type: Object as PropType, required: true + }, + tabId: { + type: Number, + required: true } }); diff --git a/renderer/src/components/main-panel/chat/message/user.vue b/renderer/src/components/main-panel/chat/message/user.vue index bbccd96..57369a0 100644 --- a/renderer/src/components/main-panel/chat/message/user.vue +++ b/renderer/src/components/main-panel/chat/message/user.vue @@ -1,22 +1,140 @@ \ No newline at end of file diff --git a/service/src/controller/index.ts b/service/src/controller/index.ts index e18f81d..1562ef0 100644 --- a/service/src/controller/index.ts +++ b/service/src/controller/index.ts @@ -83,7 +83,7 @@ export function messageController(command: string, data: any, webview: PostMessa chatCompletionService(client, data, webview); break; - case 'llm/chat/completions/cancel': + case 'llm/chat/completions/abort': abortMessageService(client, data, webview); break; diff --git a/service/src/service/llm.ts b/service/src/service/llm.ts index aac686d..2e89372 100644 --- a/service/src/service/llm.ts +++ b/service/src/service/llm.ts @@ -104,15 +104,15 @@ export function abortMessageService(client: MCPClient | undefined, data: any, we if (currentStream) { // 标记流已中止 currentStream = null; - // 发送中止消息给前端 - webview.postMessage({ - command: 'llm/chat/completions/abort', - data: { - code: 200, - msg: { - success: true - } - } - }); } + + webview.postMessage({ + command: 'llm/chat/completions/abort', + data: { + code: 200, + msg: { + success: true + } + } + }); } \ No newline at end of file