feat: add copy action to AI responses
Completed AI responses now expose a bottom copy action that copies their Markdown source without reasoning, tool logs, or citation metadata. Clipboard writes use a validated Preload/Main bridge so sandboxed Electron sessions no longer fail with a renderer clipboard permission error; full-conversation copy uses the same path. Release note: AI 回复底部现在可以直接复制 Markdown 原文,并修复了沙箱环境下回复和完整会话可能无法写入剪贴板的问题。
This commit is contained in:
@@ -5,10 +5,23 @@ import {
|
||||
browserNavigateRequestSchema,
|
||||
browserStopLoadingRequestSchema,
|
||||
builtinEmbeddingConnectionId,
|
||||
clipboardTextSchema,
|
||||
legacyEmbeddingConnectionId,
|
||||
runtimeSettingsInputSchema
|
||||
} from './contracts'
|
||||
|
||||
describe('clipboard text contract', () => {
|
||||
it('accepts text and rejects non-text input', () => {
|
||||
expect(clipboardTextSchema.parse('Markdown response')).toBe(
|
||||
'Markdown response'
|
||||
)
|
||||
expect(clipboardTextSchema.parse('')).toBe('')
|
||||
expect(clipboardTextSchema.safeParse({ text: 'no' }).success).toBe(
|
||||
false
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('browser control contracts', () => {
|
||||
it('requires authoritative toolbar metadata and accepts committed URLs up to 8192 characters', () => {
|
||||
const base = {
|
||||
|
||||
@@ -1116,6 +1116,8 @@ export type ContextFileSelectionProgress = {
|
||||
|
||||
export const maximumPastedImageBytes = 12 * 1024 * 1024
|
||||
|
||||
export const clipboardTextSchema = z.string()
|
||||
|
||||
export const pastedImageInputSchema = z
|
||||
.object({
|
||||
data: z
|
||||
@@ -1561,6 +1563,9 @@ export type DesktopApi = {
|
||||
onNewConversation: (listener: () => void) => () => void
|
||||
onOpenSettings: (listener: () => void) => () => void
|
||||
}
|
||||
clipboard: {
|
||||
writeText: (text: string) => Promise<void>
|
||||
}
|
||||
agent: {
|
||||
getStatus: (
|
||||
selection?: AgentRuntimeSelection
|
||||
|
||||
@@ -11,6 +11,7 @@ export const ipcChannels = {
|
||||
appRendererPersistenceRequest: 'app:renderer-persistence-request',
|
||||
appRendererPersistenceComplete: 'app:renderer-persistence-complete',
|
||||
appClearLocalData: 'app:clear-local-data',
|
||||
clipboardWriteText: 'clipboard:write-text',
|
||||
conversationNew: 'conversation:new',
|
||||
settingsOpen: 'settings:open',
|
||||
agentStatus: 'agent:get-status',
|
||||
|
||||
Reference in New Issue
Block a user