parent
c9813bb1e2
commit
1fbd727a7b
@ -173,4 +173,6 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
|||||||
ipcMain.handle('gemini:upload-file', GeminiService.uploadFile)
|
ipcMain.handle('gemini:upload-file', GeminiService.uploadFile)
|
||||||
ipcMain.handle('gemini:base64-file', GeminiService.base64File)
|
ipcMain.handle('gemini:base64-file', GeminiService.base64File)
|
||||||
ipcMain.handle('gemini:retrieve-file', GeminiService.retrieveFile)
|
ipcMain.handle('gemini:retrieve-file', GeminiService.retrieveFile)
|
||||||
|
ipcMain.handle('gemini:list-files', GeminiService.listFiles)
|
||||||
|
ipcMain.handle('gemini:delete-file', GeminiService.deleteFile)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,4 +50,14 @@ export class GeminiService {
|
|||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async listFiles(_: Electron.IpcMainInvokeEvent, apiKey: string) {
|
||||||
|
const fileManager = new GoogleAIFileManager(apiKey)
|
||||||
|
return await fileManager.listFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async deleteFile(_: Electron.IpcMainInvokeEvent, apiKey: string, fileId: string) {
|
||||||
|
const fileManager = new GoogleAIFileManager(apiKey)
|
||||||
|
await fileManager.deleteFile(fileId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
src/preload/index.d.ts
vendored
5
src/preload/index.d.ts
vendored
@ -1,6 +1,5 @@
|
|||||||
import { ElectronAPI } from '@electron-toolkit/preload'
|
import { ElectronAPI } from '@electron-toolkit/preload'
|
||||||
import type { FileMetadataResponse } from '@google/generative-ai/server'
|
import type { FileMetadataResponse, ListFilesResponse, UploadFileResponse } from '@google/generative-ai/server'
|
||||||
import { UploadFileResponse } from '@google/generative-ai/server'
|
|
||||||
import { AddLoaderReturn, ExtractChunkData } from '@llm-tools/embedjs-interfaces'
|
import { AddLoaderReturn, ExtractChunkData } from '@llm-tools/embedjs-interfaces'
|
||||||
import { FileType } from '@renderer/types'
|
import { FileType } from '@renderer/types'
|
||||||
import { WebDavConfig } from '@renderer/types'
|
import { WebDavConfig } from '@renderer/types'
|
||||||
@ -86,6 +85,8 @@ declare global {
|
|||||||
uploadFile: (file: FileType, apiKey: string) => Promise<UploadFileResponse>
|
uploadFile: (file: FileType, apiKey: string) => Promise<UploadFileResponse>
|
||||||
retrieveFile: (file: FileType, apiKey: string) => Promise<FileMetadataResponse | undefined>
|
retrieveFile: (file: FileType, apiKey: string) => Promise<FileMetadataResponse | undefined>
|
||||||
base64File: (file: FileType) => Promise<{ data: string; mimeType: string }>
|
base64File: (file: FileType) => Promise<{ data: string; mimeType: string }>
|
||||||
|
listFiles: (apiKey: string) => Promise<ListFilesResponse>
|
||||||
|
deleteFile: (apiKey: string, fileId: string) => Promise<void>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,9 @@ const api = {
|
|||||||
gemini: {
|
gemini: {
|
||||||
uploadFile: (file: FileType, apiKey: string) => ipcRenderer.invoke('gemini:upload-file', file, apiKey),
|
uploadFile: (file: FileType, apiKey: string) => ipcRenderer.invoke('gemini:upload-file', file, apiKey),
|
||||||
base64File: (file: FileType) => ipcRenderer.invoke('gemini:base64-file', file),
|
base64File: (file: FileType) => ipcRenderer.invoke('gemini:base64-file', file),
|
||||||
retrieveFile: (file: FileType, apiKey: string) => ipcRenderer.invoke('gemini:retrieve-file', file, apiKey)
|
retrieveFile: (file: FileType, apiKey: string) => ipcRenderer.invoke('gemini:retrieve-file', file, apiKey),
|
||||||
|
listFiles: (apiKey: string) => ipcRenderer.invoke('gemini:list-files', apiKey),
|
||||||
|
deleteFile: (apiKey: string, fileId: string) => ipcRenderer.invoke('gemini:delete-file', apiKey, fileId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { DeleteOutlined } from '@ant-design/icons'
|
import { DeleteOutlined } from '@ant-design/icons'
|
||||||
import { FileMetadataResponse, FileState } from '@google/generative-ai/server'
|
import type { FileMetadataResponse } from '@google/generative-ai/server'
|
||||||
import { useProvider } from '@renderer/hooks/useProvider'
|
import { useProvider } from '@renderer/hooks/useProvider'
|
||||||
import GeminiProvider from '@renderer/providers/GeminiProvider'
|
|
||||||
import { runAsyncFunction } from '@renderer/utils'
|
import { runAsyncFunction } from '@renderer/utils'
|
||||||
import { Table } from 'antd'
|
import { Table } from 'antd'
|
||||||
import type { ColumnsType } from 'antd/es/table'
|
import type { ColumnsType } from 'antd/es/table'
|
||||||
@ -20,9 +19,8 @@ const GeminiFiles: FC<GeminiFilesProps> = ({ id }) => {
|
|||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
const fetchFiles = useCallback(async () => {
|
const fetchFiles = useCallback(async () => {
|
||||||
const geminiProvider = new GeminiProvider(provider)
|
const { files } = await window.api.gemini.listFiles(provider.apiKey)
|
||||||
const { files } = await geminiProvider.listFiles()
|
files && setFiles(files.filter((file) => file.state === 'ACTIVE'))
|
||||||
files && setFiles(files.filter((file) => file.state === FileState.ACTIVE))
|
|
||||||
}, [provider])
|
}, [provider])
|
||||||
|
|
||||||
const columns: ColumnsType<FileMetadataResponse> = [
|
const columns: ColumnsType<FileMetadataResponse> = [
|
||||||
@ -54,13 +52,12 @@ const GeminiFiles: FC<GeminiFilesProps> = ({ id }) => {
|
|||||||
key: 'actions',
|
key: 'actions',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
const geminiProvider = new GeminiProvider(provider)
|
|
||||||
return (
|
return (
|
||||||
<DeleteOutlined
|
<DeleteOutlined
|
||||||
style={{ cursor: 'pointer', color: 'var(--color-error)' }}
|
style={{ cursor: 'pointer', color: 'var(--color-error)' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setFiles(files.filter((file) => file.name !== record.name))
|
setFiles(files.filter((file) => file.name !== record.name))
|
||||||
geminiProvider.deleteFile(record.name).catch((error) => {
|
window.api.gemini.deleteFile(provider.apiKey, record.name).catch((error) => {
|
||||||
console.error('Failed to delete file:', error)
|
console.error('Failed to delete file:', error)
|
||||||
setFiles((prev) => [...prev, record])
|
setFiles((prev) => [...prev, record])
|
||||||
})
|
})
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import {
|
|||||||
RequestOptions,
|
RequestOptions,
|
||||||
TextPart
|
TextPart
|
||||||
} from '@google/generative-ai'
|
} from '@google/generative-ai'
|
||||||
import { GoogleAIFileManager, ListFilesResponse } from '@google/generative-ai/server'
|
|
||||||
import { isEmbeddingModel, isWebSearchModel } from '@renderer/config/models'
|
import { isEmbeddingModel, isWebSearchModel } from '@renderer/config/models'
|
||||||
import { getStoreSetting } from '@renderer/hooks/useSettings'
|
import { getStoreSetting } from '@renderer/hooks/useSettings'
|
||||||
import i18n from '@renderer/i18n'
|
import i18n from '@renderer/i18n'
|
||||||
@ -345,14 +344,4 @@ export default class GeminiProvider extends BaseProvider {
|
|||||||
const data = await this.sdk.getGenerativeModel({ model: model.id }, this.requestOptions).embedContent('hi')
|
const data = await this.sdk.getGenerativeModel({ model: model.id }, this.requestOptions).embedContent('hi')
|
||||||
return data.embedding.values.length
|
return data.embedding.values.length
|
||||||
}
|
}
|
||||||
|
|
||||||
public async listFiles(): Promise<ListFilesResponse> {
|
|
||||||
const fileManager = new GoogleAIFileManager(this.apiKey)
|
|
||||||
return await fileManager.listFiles()
|
|
||||||
}
|
|
||||||
|
|
||||||
public async deleteFile(fileId: string): Promise<void> {
|
|
||||||
const fileManager = new GoogleAIFileManager(this.apiKey)
|
|
||||||
await fileManager.deleteFile(fileId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user