Skip to main content

Preload API

Elftia uses Electron's contextBridge to securely expose backend capabilities to the frontend. The frontend calls all backend functionality through the window.api global object.

Authentication

All IPC calls automatically carry an authentication token — you never need to handle this manually:

{/* packages/desktop/app/preload/index.ts — simplified illustration */}

const authToken = ipcRenderer.sendSync('auth:bootstrap');

const invoke = (channel: string, ...args: any[]) =>
ipcRenderer.invoke(channel, authToken, ...args);

Namespace Index

NamespaceResponsibilityMethods
runtimeRuntime environment1
authSessionAuthentication session8
accountAccount management7
projectsProject management6
filesFile operations12
sessionsProject sessions3
chatChat core6
chatSessionsChat session CRUD5
chatMessagesChat message CRUD7
chatAssistantsChat assistant CRUD6
completionLLM completion10
llmConfigLLM configuration30+
settingsApp settings4
appPreferencesApp preferences2
configFile config7
themeTheme management11
mcpMCP servers12
agentAgent operations15+
magiMagi service4
elfiElfi assistant3
imageImage generation3
videoVideo generation3
musicMusic generation1
mediaMedia management10
webSearchWeb search9
windowControlsWindow controls7
diagnosticsSystem diagnostics6
envEnvironment detection5
gitGit operations2
promptsPrompt management9
exportExport functionality2
channelPluginsChannel plugins6

runtime

window.api.runtime.getEnvironment(): Promise<RuntimeEnvironment>

Returns runtime environment information (platform, version, paths, etc.).


authSession

window.api.authSession.getState(): Promise<AuthState>
window.api.authSession.startBrowserLogin(): Promise<void>
window.api.authSession.refresh(): Promise<void>
window.api.authSession.syncProfile(): Promise<void>
window.api.authSession.getAccessToken(): Promise<string>
window.api.authSession.logout(): Promise<void>
window.api.authSession.retrySteamLogin(): Promise<void>
window.api.authSession.subscribe(cb: (state: AuthState) => void): () => void

subscribe returns an unsubscribe function.


account

window.api.account.list(type?: string): Promise<Account[]>
window.api.account.create(payload: CreateAccountInput): Promise<Account>
window.api.account.delete(id: string): Promise<void>
window.api.account.toggle(id: string, isActive: boolean): Promise<void>
window.api.account.reveal(id: string): Promise<string>
window.api.account.export(options?: ExportOptions): Promise<ExportResult>
window.api.account.clear(type?: string): Promise<void>

projects

window.api.projects.list(): Promise<Project[]>
window.api.projects.create(input: { path: string; displayName?: string }): Promise<Project>
window.api.projects.rename(projectId: string, displayName?: string): Promise<void>
window.api.projects.delete(projectId: string): Promise<void>
window.api.projects.browse(dirPath?: string): Promise<BrowseResult>
window.api.projects.createWorkspace(payload: { path: string; workspaceType: string }): Promise<void>

files

window.api.files.snapshot(projectId: string): Promise<FileTree>
window.api.files.subscribe(projectId: string, cb: (patch: FilePatch) => void): () => void
window.api.files.watch(projectId: string): Promise<void>
window.api.files.unwatch(projectId: string): Promise<void>
window.api.files.read(projectId: string, filePath: string): Promise<string>
window.api.files.readBinary(projectId: string, filePath: string): Promise<Buffer>
window.api.files.write(projectId: string, filePath: string, content: string): Promise<void>
window.api.files.shallow(projectId: string, dirPath?: string): Promise<FileEntry[]>
window.api.files.search(projectId: string, params?: SearchParams): Promise<SearchResult[]>
window.api.files.searchMetrics(): Promise<SearchMetrics>
window.api.files.revealInFolder(filePath: string): Promise<void>
window.api.files.clearCache(projectId: string): Promise<void>

chat

window.api.chat.appendMessage(sessionId: string, msg: any): Promise<void>
window.api.chat.getMessages(sessionId: string, query?: any): Promise<Message[]>
window.api.chat.sendCommand(payload: CommandPayload): Promise<void>
window.api.chat.abortSession(payload: { sessionId: string }): Promise<void>
window.api.chat.checkSessionStatus(payload: { sessionId: string }): Promise<SessionStatus>
window.api.chat.onEvent(cb: (data: ChatEvent) => void): () => void

chatSessions

window.api.chatSessions.list(query?: ListQuery): Promise<ChatSession[]>
window.api.chatSessions.get(id: string): Promise<ChatSession>
window.api.chatSessions.create(input: CreateChatSessionInput): Promise<ChatSession>
window.api.chatSessions.update(id: string, input: UpdateInput): Promise<ChatSession>
window.api.chatSessions.delete(id: string): Promise<void>

chatMessages

window.api.chatMessages.getActivePath(sessionId: string): Promise<Message[]>
window.api.chatMessages.getPage(query: PageQuery): Promise<PageResult>
window.api.chatMessages.getBranches(sessionId: string, parentId: string | null): Promise<Message[]>
window.api.chatMessages.append(sessionId: string, message: MessageInput): Promise<Message>
window.api.chatMessages.update(messageId: string, updates: MessageUpdate): Promise<Message>
window.api.chatMessages.switchBranch(messageId: string): Promise<void>
window.api.chatMessages.delete(messageId: string): Promise<void>

chatAssistants

window.api.chatAssistants.list(): Promise<ChatAssistant[]>
window.api.chatAssistants.get(id: string): Promise<ChatAssistant>
window.api.chatAssistants.create(input: CreateAssistantInput): Promise<ChatAssistant>
window.api.chatAssistants.update(id: string, input: UpdateInput): Promise<ChatAssistant>
window.api.chatAssistants.delete(id: string): Promise<void>
window.api.chatAssistants.setDefault(id: string): Promise<void>

completion

window.api.completion.complete(payload: CompletePayload): Promise<CompleteResult>
window.api.completion.stream(payload: StreamPayload): Promise<{ streamId: string }>
window.api.completion.onStreamEvent(streamId: string, cb: (data: StreamEvent) => void): () => void
window.api.completion.getModels(providerId: string): Promise<Model[]>
window.api.completion.testModel(providerId: string, modelId: string): Promise<TestResult>
window.api.completion.chatInSession(payload: ChatInSessionPayload): Promise<void>
window.api.completion.regenerateInSession(payload: RegeneratePayload): Promise<void>
window.api.completion.onChatCompleted(cb: (data: ChatCompletedEvent) => void): () => void
window.api.completion.createRPFirstMessage(payload: { sessionId: string }): Promise<void>

llmConfig

{/* Provider CRUD */}
window.api.llmConfig.getProviders(): Promise<Provider[]>
window.api.llmConfig.getProvider(id: string): Promise<Provider>
window.api.llmConfig.addProvider(payload: AddProviderInput): Promise<Provider>
window.api.llmConfig.updateProvider(payload: UpdateProviderInput): Promise<Provider>
window.api.llmConfig.deleteProvider(id: string): Promise<void>
window.api.llmConfig.toggleProvider(id: string, enabled: boolean): Promise<void>
window.api.llmConfig.discoverModels(id: string, options?: { forceRefresh?: boolean }): Promise<Model[]>

{/* Presets */}
window.api.llmConfig.getProviderPresets(): Promise<Preset[]>
window.api.llmConfig.addFromPreset(payload: { presetId: string; apiKey?: string }): Promise<Provider>

{/* Model parameters */}
window.api.llmConfig.getAgentDefaultModels(): Promise<DefaultModels>
window.api.llmConfig.setAgentDefaultModels(payload: DefaultModels): Promise<void>
window.api.llmConfig.getGlobalModelParameters(): Promise<GlobalModelParameters>
window.api.llmConfig.setGlobalModelParameters(payload: GlobalModelParameters): Promise<void>

{/* API key pool */}
window.api.llmConfig.getApiKeys(providerId: string): Promise<ApiKeyEntry[]>
window.api.llmConfig.addApiKey(input: ApiKeyInput): Promise<ApiKeyEntry>
window.api.llmConfig.updateApiKey(id: string, updates: ApiKeyUpdate): Promise<ApiKeyEntry>
window.api.llmConfig.deleteApiKey(id: string): Promise<void>
window.api.llmConfig.toggleApiKey(id: string, enabled: boolean): Promise<void>

{/* Import/export */}
window.api.llmConfig.exportConfig(): Promise<ExportedConfig>
window.api.llmConfig.importConfig(payload: ExportedConfig): Promise<void>

settings

window.api.settings.get(key: string): Promise<any>
window.api.settings.set(key: string, value: any): Promise<void>
window.api.settings.getExperimentalFeatures(): Promise<ExperimentalFeatures>
window.api.settings.setExperimentalFeatures(payload: ExperimentalFeatures): Promise<void>

appPreferences

window.api.appPreferences.get(): Promise<AppPreferences>
window.api.appPreferences.update(payload: Partial<AppPreferences>): Promise<void>

config

window.api.config.get(key: string): Promise<any>
window.api.config.getAll(): Promise<Record<string, any>>
window.api.config.getPath(): Promise<string>
window.api.config.set(key: string, value: any): Promise<void>
window.api.config.merge(key: string, patch: any): Promise<void>
window.api.config.reset(key: string): Promise<void>
window.api.config.onChange(cb: (event: ConfigChangeEvent) => void): () => void

theme

window.api.theme.getState(): Promise<ThemeState>
window.api.theme.setMode(mode: 'light' | 'dark' | 'system'): Promise<void>
window.api.theme.updateUserTheme(payload: UserThemeUpdate): Promise<void>
window.api.theme.setCustomCss(css: string): Promise<void>
window.api.theme.setWallpaper(payload: WallpaperConfig): Promise<void>
window.api.theme.setWallpaperPreferences(payload: WallpaperPreferences): Promise<void>
window.api.theme.setRemoteAssetsPolicy(payload: RemoteAssetsPolicy): Promise<void>
window.api.theme.exportProfile(): Promise<ThemeProfile>
window.api.theme.importProfile(payload: ThemeProfile): Promise<void>
window.api.theme.resetProfile(): Promise<void>
window.api.theme.onUpdated(cb: (state: ThemeState) => void): () => void

mcp

window.api.mcp.list(): Promise<McpServer[]>
window.api.mcp.add(payload: AddMcpInput): Promise<McpServer>
window.api.mcp.addJson(payload: JsonMcpConfig): Promise<McpServer>
window.api.mcp.remove(payload: { id: string }): Promise<void>
window.api.mcp.test(payload: { id: string }): Promise<TestResult>
window.api.mcp.discover(payload: { id: string }): Promise<DiscoveryResult>
window.api.mcp.update(payload: { id: string; updates: McpUpdate }): Promise<void>
window.api.mcp.listServerTools(serverId: string): Promise<Tool[]>
window.api.mcp.listAllTools(): Promise<Tool[]>
window.api.mcp.callTool(payload: CallToolInput): Promise<ToolResult>
window.api.mcp.checkDependency(command: string): Promise<boolean>
window.api.mcp.installDependency(command: string): Promise<void>

agent

window.api.agent.checkAvailability(): Promise<boolean>
window.api.agent.getBackends(): Promise<BackendInfo[]>
window.api.agent.createSession(options: CreateSessionOptions): Promise<{ sessionId: string }>
window.api.agent.resumeSession(params: ResumeParams): Promise<void>
window.api.agent.interrupt(sessionId: string): Promise<void>
window.api.agent.respondPermission(params: { requestId: string; result: any }): Promise<void>
window.api.agent.respondAskUserQuestion(params: { requestId: string; result: { answers: Record<string, string>; annotations?: Record<string, { notes?: string }>; cancelled?: boolean } }): Promise<{ success: boolean }>
window.api.agent.getActiveSessions(): Promise<ActiveSession[]>
window.api.agent.isSessionActive(sessionId: string): Promise<boolean>
window.api.agent.selectFolder(): Promise<{ canceled: boolean; path: string | null }>
window.api.agent.onEvent(cb: (data: AgentEvent) => void): () => void
window.api.agent.onPermissionRequest(cb: (data: PermissionRequest) => void): () => void
window.api.agent.onAskUserQuestion(cb: (data: AskUserQuestionRequest) => void): () => void
window.api.agent.onA2UIRender(cb: (data: A2UIEvent) => void): () => void
window.api.agent.onDevPreview(cb: (data: PreviewStatus) => void): () => void

{/* Sub-namespaces */}
window.api.agent.customAgents.list/get/create/update/delete/run/export/import(...)
window.api.agent.mcpRefs.list/attach/detach/toggleEnabled(...)
window.api.agent.agentSessions.create/get/list/update/delete(...)
window.api.agent.sharedComponents.create/get/list/update/delete(...)
window.api.agent.personas.list/get/create/update/delete(...)

image

window.api.image.generate(payload: ImageGeneratePayload): Promise<ImageResult>
window.api.image.generateInSession(payload: SessionImagePayload): Promise<void>
window.api.image.onGenerationCompleted(cb: (data: GenerationCompletedEvent) => void): () => void

video

window.api.video.generate(payload: VideoGeneratePayload): Promise<VideoResult>
window.api.video.generateInSession(payload: SessionVideoPayload): Promise<void>
window.api.video.onGenerationCompleted(cb: (data: GenerationCompletedEvent) => void): () => void

music

window.api.music.generateInSession(payload: SessionMusicPayload): Promise<void>

sessions

window.api.sessions.list(projectId: string, query?: any): Promise<Session[]>
window.api.sessions.delete(projectId: string, sessionId: string): Promise<void>
window.api.sessions.getTokenUsage(projectId: string, sessionId: string): Promise<TokenUsage>

magi

window.api.magi.getStatus(): Promise<MagiStatus>
window.api.magi.getConfig(): Promise<MagiConfig>
window.api.magi.updateConfig(payload: Partial<MagiConfig>): Promise<void>
window.api.magi.resetSession(): Promise<void>

elfi

window.api.elfi.ask(payload: { question: string; context?: string }): Promise<ElfiResponse>
window.api.elfi.getKnowledge(path: string): Promise<string>
window.api.elfi.searchKnowledge(query: string): Promise<KnowledgeResult[]>

media

window.api.media.migrateBase64ToFiles(): Promise<MigrationResult>
window.api.media.getMigrationStatus(): Promise<MigrationStatus>
window.api.media.onMigrationProgress(cb: (data: ProgressEvent) => void): () => void
window.api.media.generateMissingThumbnails(): Promise<MigrationResult>
window.api.media.onThumbnailProgress(cb: (data: ProgressEvent) => void): () => void
window.api.media.compressImage(payload: { base64: string; mimeType: string }): Promise<CompressResult>
window.api.media.compressDataUrl(dataUrl: string): Promise<CompressResult>
window.api.media.compressMany(payload: CompressInput[]): Promise<CompressResult[]>
window.api.media.migrateAttachmentsToFiles(): Promise<MigrationResult>
window.api.media.getAttachmentMigrationStatus(): Promise<MigrationStatus>

env

window.api.env.checkAll(options?: { force?: boolean }): Promise<EnvCheckResult>
window.api.env.installTool(name: string): Promise<void>
window.api.env.repairAll(): Promise<void>
window.api.env.getLastResult(): Promise<EnvCheckResult>
window.api.env.onProgress(cb: (data: ProgressEvent) => void): () => void

git

window.api.git.status(projectId: string): Promise<GitStatus>
window.api.git.diff(projectId: string, filePath: string, options?: { staged?: boolean; isUntracked?: boolean }): Promise<string>

prompts

window.api.prompts.list(query?: ListQuery): Promise<Prompt[]>
window.api.prompts.get(id: string): Promise<Prompt>
window.api.prompts.create(input: CreatePromptInput): Promise<Prompt>
window.api.prompts.update(id: string, input: UpdatePromptInput): Promise<Prompt>
window.api.prompts.delete(id: string): Promise<void>
window.api.prompts.reorder(ids: string[], sortOrders: number[]): Promise<void>
window.api.prompts.incrementUsage(id: string): Promise<void>
window.api.prompts.search(query: string, limit?: number): Promise<Prompt[]>
window.api.prompts.quickList(): Promise<Prompt[]>

export

window.api.export.sessions(input: ExportSessionsInput): Promise<ExportResult[]>
window.api.export.messages(input: ExportMessagesInput): Promise<ExportResult>

channelPlugins

window.api.channelPlugins.listPlugins(): Promise<ChannelPlugin[]>
window.api.channelPlugins.listInstances(): Promise<ChannelInstance[]>
window.api.channelPlugins.add(payload: AddChannelInput): Promise<ChannelInstance>
window.api.channelPlugins.remove(id: string): Promise<void>
window.api.channelPlugins.update(payload: UpdateChannelInput): Promise<void>
window.api.channelPlugins.changeStatus(payload: { id: string; status: ChannelStatus }): Promise<void>

webSearch

window.api.webSearch.search(query: string, providerId: string, options?: SearchOptions): Promise<SearchResult[]>
window.api.webSearch.configureProvider(config: ProviderConfig): Promise<void>
window.api.webSearch.configureProviders(configs: ProviderConfig[]): Promise<void>
window.api.webSearch.isProviderEnabled(providerId: string): Promise<boolean>
window.api.webSearch.getProviderConfig(providerId: string): Promise<ProviderConfig>
window.api.webSearch.getProviders(): Promise<Provider[]>
window.api.webSearch.jinaReader(url: string, options?: { timeout?: number }): Promise<string>
window.api.webSearch.isAvailable(): Promise<boolean>

windowControls

window.api.windowControls.minimize(): Promise<void>
window.api.windowControls.toggleMaximize(): Promise<void>
window.api.windowControls.close(): Promise<void>
window.api.windowControls.toggleDevTools(): Promise<void>
window.api.windowControls.getDeveloperMode(): Promise<boolean>
window.api.windowControls.enableDeveloperMode(): Promise<void>
window.api.windowControls.disableDeveloperMode(): Promise<void>

diagnostics

window.api.diagnostics.dump(): Promise<DiagnosticsData>
window.api.diagnostics.export(options: ExportOptions): Promise<string>
window.api.diagnostics.bundle(options: BundleOptions): Promise<string>
window.api.diagnostics.clearCaches(): Promise<void>
window.api.diagnostics.dbVacuum(): Promise<void>
window.api.diagnostics.dbGetSize(): Promise<number>

Event Subscription Pattern

All onXxx methods return an unsubscribe function. Typical usage:

useEffect(() => {
const unsubscribe = window.api.chat.onEvent((data) => {
handleChatEvent(data);
});
return unsubscribe; // automatically unsubscribes when the component unmounts
}, []);

Key Event Channels Summary

MethodPush ChannelEvent Content
authSession.subscribeauthSession:stateAuth state change
chat.onEventchat:eventChat streaming events
completion.onStreamEventcompletion:stream:{id}Completion streaming events
completion.onChatCompletedchat:completedChat completed
image.onGenerationCompletedgeneration:completedImage generation completed
video.onGenerationCompletedvideo:generation:completedVideo generation completed
agent.onEventagent:eventAgent events
agent.onPermissionRequestagent:permissionRequestPermission requests
agent.onAskUserQuestionagent:askUserQuestionAgent question (ask_user_question MCP)
theme.onUpdatedtheme:updatedTheme changes
config.onChangeconfig:changedConfig changes
files.subscribefiles:patch:{projectId}File change patches
env.onProgressenv:progressEnvironment check progress