diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/ApplyBlockHoverButtons.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/ApplyBlockHoverButtons.tsx new file mode 100644 index 00000000..c7f4b52c --- /dev/null +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/ApplyBlockHoverButtons.tsx @@ -0,0 +1,84 @@ +import { useState, useEffect, useCallback } from 'react' +import { useAccessor } from '../util/services.js' + +enum CopyButtonText { + Idle = 'Copy', + Copied = 'Copied!', + Error = 'Could not copy', +} + +const COPY_FEEDBACK_TIMEOUT = 1000 // amount of time to say 'Copied!' + +const CopyButton = ({ codeStr }: { codeStr: string }) => { + const accessor = useAccessor() + + const metricsService = accessor.get('IMetricsService') + const clipboardService = accessor.get('IClipboardService') + const [copyButtonText, setCopyButtonText] = useState(CopyButtonText.Idle) + + useEffect(() => { + if (copyButtonText === CopyButtonText.Idle) return + setTimeout(() => { + setCopyButtonText(CopyButtonText.Idle) + }, COPY_FEEDBACK_TIMEOUT) + }, [copyButtonText]) + + + const onCopy = useCallback(() => { + clipboardService.writeText(codeStr) + .then(() => { setCopyButtonText(CopyButtonText.Copied) }) + .catch(() => { setCopyButtonText(CopyButtonText.Error) }) + metricsService.capture('Copy Code', { length: codeStr.length }) // capture the length only + }, [metricsService, clipboardService, codeStr]) + + const isSingleLine = !codeStr.includes('\n') + + return +} + + + +const ApplyButton = ({ codeStr }: { codeStr: string }) => { + const accessor = useAccessor() + + const editCodeService = accessor.get('IEditCodeService') + const metricsService = accessor.get('IMetricsService') + + + const onApply = useCallback(() => { + + editCodeService.startApplying({ + from: 'ClickApply', + type: 'searchReplace', + applyStr: codeStr, + }) + metricsService.capture('Apply Code', { length: codeStr.length }) // capture the length only + }, [metricsService, editCodeService, codeStr]) + + const isSingleLine = !codeStr.includes('\n') + + return + +} + + + + + +export const ApplyBlockHoverButtons = ({ codeStr }: { codeStr: string }) => { + return <> + + + +} diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx index 7a9953b7..6f737ccb 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx @@ -3,22 +3,12 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ -import React, { JSX, useCallback, useEffect, useState } from 'react' +import React, { JSX } from 'react' import { marked, MarkedToken, Token } from 'marked' import { BlockCode } from './BlockCode.js' -import { useAccessor, useChatThreadsState, useChatThreadsStreamState } from '../util/services.js' import { ChatMessageLocation, } from '../../../aiRegexService.js' import { nameToVscodeLanguage } from '../../../helpers/detectLanguage.js' - - -enum CopyButtonState { - Copy = 'Copy', - Copied = 'Copied!', - Error = 'Could not copy', -} - -const COPY_FEEDBACK_TIMEOUT = 1000 // amount of time to say 'Copied!' - +import { ApplyBlockHoverButtons } from './ApplyBlockHoverButtons.js' type ApplyBoxLocation = ChatMessageLocation & { tokenIdx: string } @@ -29,60 +19,6 @@ const getApplyBoxId = ({ threadId, messageIdx, tokenIdx }: ApplyBoxLocation) => -const ApplyButtonsOnHover = ({ applyStr }: { applyStr: string }) => { - const accessor = useAccessor() - - const [copyButtonState, setCopyButtonState] = useState(CopyButtonState.Copy) - const editCodeService = accessor.get('IEditCodeService') - const clipboardService = accessor.get('IClipboardService') - const metricsService = accessor.get('IMetricsService') - - useEffect(() => { - - if (copyButtonState !== CopyButtonState.Copy) { - setTimeout(() => { - setCopyButtonState(CopyButtonState.Copy) - }, COPY_FEEDBACK_TIMEOUT) - } - }, [copyButtonState]) - - const onCopy = useCallback(() => { - clipboardService.writeText(applyStr) - .then(() => { setCopyButtonState(CopyButtonState.Copied) }) - .catch(() => { setCopyButtonState(CopyButtonState.Error) }) - metricsService.capture('Copy Code', { length: applyStr.length }) // capture the length only - - }, [metricsService, clipboardService, applyStr]) - - const onApply = useCallback(() => { - - editCodeService.startApplying({ - from: 'ClickApply', - type: 'searchReplace', - applyStr, - }) - metricsService.capture('Apply Code', { length: applyStr.length }) // capture the length only - }, [metricsService, editCodeService, applyStr]) - - const isSingleLine = !applyStr.includes('\n') - - return <> - - - -} - export const CodeSpan = ({ children, className }: { children: React.ReactNode, className?: string }) => { return } + buttonsOnHover={} /> } diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index e9169280..30351697 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -703,7 +703,7 @@ const ChatBubble = ({ chatMessage, isLoading, messageIdx }: { chatMessage: ChatM className={` relative ${mode === 'edit' ? 'px-2 w-full max-w-full' - : role === 'user' ? `px-2 self-end w-fit max-w-full whitespace-pre-wrap` // user words should be pre + : role === 'user' ? `my-0.5 px-2 self-end w-fit max-w-full whitespace-pre-wrap` // user words should be pre : role === 'assistant' ? `px-2 self-start w-full max-w-full` : '' } `} diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index 96337d33..529a872c 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -545,7 +545,7 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName return { title: providerName === 'ollama' ? 'Endpoint' : providerName === 'vLLM' ? 'Endpoint' : - providerName === 'openAICompatible' ? 'baseURL' :// (do not include /chat/completions) + providerName === 'openAICompatible' ? 'baseURL' : // (do not include /chat/completions) '(never)', placeholder: providerName === 'ollama' ? defaultProviderSettings.ollama.endpoint diff --git a/src/vs/workbench/contrib/void/electron-main/llmMessage/openai.ts b/src/vs/workbench/contrib/void/electron-main/llmMessage/openai.ts index 37b8b468..7769a983 100644 --- a/src/vs/workbench/contrib/void/electron-main/llmMessage/openai.ts +++ b/src/vs/workbench/contrib/void/electron-main/llmMessage/openai.ts @@ -10,12 +10,12 @@ import { InternalToolInfo } from '../../common/toolsService.js'; import { addSystemMessageAndToolSupport } from './preprocessLLMMessages.js'; import { developerInfoOfModelName, developerInfoOfProviderName } from '../../common/voidSettingsTypes.js'; import { isAToolName } from './postprocessToolCalls.js'; -// import { parseMaxTokensStr } from './util.js'; // developer command - https://cdn.openai.com/spec/model-spec-2024-05-08.html#follow-the-chain-of-command // prompting - https://platform.openai.com/docs/guides/reasoning#advice-on-prompting +// npm i @openrouter/ai-sdk-provider ai ollama-ai-provider export const toOpenAITool = (toolInfo: InternalToolInfo) => { const { name, description, params, required } = toolInfo @@ -201,7 +201,7 @@ export const sendOpenAIChat: _InternalSendLLMChatMessageFnType = ({ messages: me // message let newText = '' newText += chunk.choices[0]?.delta?.content ?? '' - console.log('!!!!', chunk.choices[0]?.delta) + console.log('!!!!', JSON.stringify(chunk, null, 2)) fullText += newText; onText({ newText, fullText });