mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
add download chat buttons
This commit is contained in:
parent
d99d2cca4a
commit
664428c8f0
3 changed files with 53 additions and 10 deletions
|
|
@ -69,7 +69,7 @@ export const IconShell1 = ({ onClick, Icon, disabled, className, ...props }: Ico
|
|||
|
||||
const COPY_FEEDBACK_TIMEOUT = 1500 // amount of time to say 'Copied!'
|
||||
|
||||
export const CopyButton = ({ codeStr }: { codeStr: string }) => {
|
||||
export const CopyButton = ({ codeStr, toolTipName }: { codeStr: string | (() => Promise<string> | string), toolTipName: string }) => {
|
||||
const accessor = useAccessor()
|
||||
|
||||
const metricsService = accessor.get('IMetricsService')
|
||||
|
|
@ -83,8 +83,8 @@ export const CopyButton = ({ codeStr }: { codeStr: string }) => {
|
|||
}, COPY_FEEDBACK_TIMEOUT)
|
||||
}, [copyButtonText])
|
||||
|
||||
const onCopy = useCallback(() => {
|
||||
clipboardService.writeText(codeStr)
|
||||
const onCopy = useCallback(async () => {
|
||||
clipboardService.writeText(typeof codeStr === 'string' ? codeStr : await codeStr())
|
||||
.then(() => { setCopyButtonText(CopyButtonText.Copied) })
|
||||
.catch(() => { setCopyButtonText(CopyButtonText.Error) })
|
||||
metricsService.capture('Copy Code', { length: codeStr.length }) // capture the length only
|
||||
|
|
@ -93,7 +93,7 @@ export const CopyButton = ({ codeStr }: { codeStr: string }) => {
|
|||
return <IconShell1
|
||||
Icon={copyButtonText === CopyButtonText.Copied ? Check : copyButtonText === CopyButtonText.Error ? X : Copy}
|
||||
onClick={onCopy}
|
||||
{...tooltipPropsForApplyBlock({ tooltipName: 'Copy' })}
|
||||
{...tooltipPropsForApplyBlock({ tooltipName: toolTipName })}
|
||||
/>
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +374,7 @@ export const BlockCodeApplyWrapper = ({
|
|||
</div>
|
||||
<div className={`${canApply ? '' : 'hidden'} flex items-center gap-1`}>
|
||||
<JumpToFileButton uri={uri} />
|
||||
{currStreamState === 'idle-no-changes' && <CopyButton codeStr={initValue} />}
|
||||
{currStreamState === 'idle-no-changes' && <CopyButton codeStr={initValue} toolTipName='Copy' />}
|
||||
<ApplyButtonsHTML uri={uri} applyBoxId={applyBoxId} codeStr={initValue} reapplyIcon={false} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ import { ModelDropdown, } from '../void-settings-tsx/ModelDropdown.js';
|
|||
import { SidebarThreadSelector } from './SidebarThreadSelector.js';
|
||||
import { VOID_CTRL_L_ACTION_ID } from '../../../actionIDs.js';
|
||||
import { VOID_OPEN_SETTINGS_ACTION_ID } from '../../../voidSettingsPane.js';
|
||||
import { ChatMode, FeatureName, isFeatureNameDisabled } from '../../../../../../../workbench/contrib/void/common/voidSettingsTypes.js';
|
||||
import { ChatMode, displayInfoOfProviderName, FeatureName, isFeatureNameDisabled } from '../../../../../../../workbench/contrib/void/common/voidSettingsTypes.js';
|
||||
import { WarningBox } from '../void-settings-tsx/WarningBox.js';
|
||||
import { getModelCapabilities, getIsReasoningEnabledState } from '../../../../common/modelCapabilities.js';
|
||||
import { AlertTriangle, Ban, Check, ChevronRight, Dot, FileIcon, Pencil, Undo, Undo2, X, Flag } from 'lucide-react';
|
||||
import { AlertTriangle, Ban, Check, ChevronRight, Dot, FileIcon, Pencil, Undo, Undo2, X, Flag, Copy as CopyIcon } from 'lucide-react';
|
||||
import { ChatMessage, CheckpointEntry, StagingSelectionItem, ToolMessage } from '../../../../common/chatThreadServiceTypes.js';
|
||||
import { LintErrorItem, ToolCallParams, ToolNameWithApproval } from '../../../../common/toolsServiceTypes.js';
|
||||
import { ApplyButtonsHTML, CopyButton, IconShell1, JumpToFileButton, JumpToTerminalButton, StatusIndicator, StatusIndicatorForApplyButton, useApplyButtonState } from '../markdown/ApplyBlockHoverButtons.js';
|
||||
|
|
@ -1390,7 +1390,7 @@ const EditToolHeaderButtons = ({ applyBoxId, uri, codeStr }: { applyBoxId: strin
|
|||
|
||||
<StatusIndicatorForApplyButton applyBoxId={applyBoxId} uri={uri} />
|
||||
<JumpToFileButton uri={uri} />
|
||||
{currStreamState === 'idle-no-changes' && <CopyButton codeStr={codeStr} />}
|
||||
{currStreamState === 'idle-no-changes' && <CopyButton codeStr={codeStr} toolTipName='Copy' />}
|
||||
<ApplyButtonsHTML applyBoxId={applyBoxId} uri={uri} codeStr={codeStr} reapplyIcon={true} />
|
||||
</div>
|
||||
}
|
||||
|
|
@ -1578,11 +1578,12 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper<T>,
|
|||
const componentParams: ToolHeaderParams = { title, desc1, isError, icon }
|
||||
|
||||
if (toolMessage.type === 'success') {
|
||||
const { params, result } = toolMessage
|
||||
const { params, result, rawParams } = toolMessage
|
||||
componentParams.numResults = result.uris.length
|
||||
componentParams.hasNextPage = result.hasNextPage
|
||||
componentParams.children = result.uris.length === 0 ? undefined
|
||||
: <ToolChildrenWrapper>
|
||||
{rawParams.search_in_folder ? `Search in ${rawParams.search_in_folder}` : null}
|
||||
{result.uris.map((uri, i) => (<ListableToolItem key={i}
|
||||
name={getBasename(uri.fsPath)}
|
||||
className='w-full overflow-auto'
|
||||
|
|
@ -1622,11 +1623,12 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper<T>,
|
|||
const componentParams: ToolHeaderParams = { title, desc1, isError, icon }
|
||||
|
||||
if (toolMessage.type === 'success') {
|
||||
const { params, result } = toolMessage
|
||||
const { params, result, rawParams } = toolMessage
|
||||
componentParams.numResults = result.uris.length
|
||||
componentParams.hasNextPage = result.hasNextPage
|
||||
componentParams.children = result.uris.length === 0 ? undefined
|
||||
: <ToolChildrenWrapper>
|
||||
{rawParams.search_in_folder ? `Search in ${rawParams.search_in_folder}` : null}
|
||||
{result.uris.map((uri, i) => (<ListableToolItem key={i}
|
||||
name={getBasename(uri.fsPath)}
|
||||
className='w-full overflow-auto'
|
||||
|
|
@ -2121,9 +2123,48 @@ const CommandBarInChat = () => {
|
|||
const accessor = useAccessor()
|
||||
const editCodeService = accessor.get('IEditCodeService')
|
||||
const commandService = accessor.get('ICommandService')
|
||||
const chatThreadsService = accessor.get('IChatThreadService')
|
||||
const chatThreadsState = useChatThreadsState()
|
||||
const chatThreadsStreamState = useChatThreadsStreamState(chatThreadsState.currentThreadId)
|
||||
|
||||
const settingsState = useSettingsState()
|
||||
const convertService = accessor.get('IConvertToLLMMessageService')
|
||||
|
||||
|
||||
|
||||
const currentThread = chatThreadsService.getCurrentThread()
|
||||
const chatMode = settingsState.globalSettings.chatMode
|
||||
const modelSelection = settingsState.modelSelectionOfFeature?.Chat ?? null
|
||||
|
||||
const copyChatButton = <CopyButton
|
||||
codeStr={async () => {
|
||||
const { messages } = await convertService.prepareLLMChatMessages({
|
||||
chatMessages: currentThread.messages,
|
||||
chatMode,
|
||||
modelSelection,
|
||||
})
|
||||
return JSON.stringify(messages, null, 2)
|
||||
}}
|
||||
toolTipName={modelSelection === null ? 'Copy As Messages Payload' : `Copy As ${displayInfoOfProviderName(modelSelection.providerName).title} Payload`}
|
||||
/>
|
||||
|
||||
const copyChatButton2 = <CopyButton
|
||||
codeStr={async () => {
|
||||
return JSON.stringify(currentThread.messages, null, 2)
|
||||
}}
|
||||
toolTipName={`Copy As Void Chat`}
|
||||
/>
|
||||
|
||||
// (
|
||||
// <IconShell1
|
||||
// Icon={CopyIcon}
|
||||
// onClick={copyChatToClipboard}
|
||||
// data-tooltip-id='void-tooltip'
|
||||
// data-tooltip-place='top'
|
||||
// data-tooltip-content='Copy chat JSON'
|
||||
// />
|
||||
// )
|
||||
|
||||
const [fileDetailsOpenedState, setFileDetailsOpenedState] = useState<'auto-opened' | 'auto-closed' | 'user-opened' | 'user-closed'>('auto-closed');
|
||||
const isFileDetailsOpened = fileDetailsOpenedState === 'auto-opened' || fileDetailsOpenedState === 'user-opened';
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import { IVoidCommandBarService } from '../../../voidCommandBarService.js'
|
|||
import { INativeHostService } from '../../../../../../../platform/native/common/native.js';
|
||||
import { IEditCodeService } from '../../../editCodeServiceInterface.js'
|
||||
import { IToolsService } from '../../../toolsService.js'
|
||||
import { IConvertToLLMMessageService } from '../../../convertToLLMMessageService.js'
|
||||
|
||||
|
||||
// normally to do this you'd use a useEffect that calls .onDidChangeState(), but useEffect mounts too late and misses initial state changes
|
||||
|
|
@ -217,6 +218,7 @@ const getReactAccessor = (accessor: ServicesAccessor) => {
|
|||
IVoidCommandBarService: accessor.get(IVoidCommandBarService),
|
||||
INativeHostService: accessor.get(INativeHostService),
|
||||
IToolsService: accessor.get(IToolsService),
|
||||
IConvertToLLMMessageService: accessor.get(IConvertToLLMMessageService),
|
||||
|
||||
} as const
|
||||
return reactAccessor
|
||||
|
|
|
|||
Loading…
Reference in a new issue