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 2da98f8..6a0068a 100644 Binary files a/renderer/public/iconfont.woff2 and b/renderer/public/iconfont.woff2 differ 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