Fixes #214 --------- Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
829 lines
22 KiB
TypeScript
829 lines
22 KiB
TypeScript
import type { IpcRenderer } from "electron";
|
|
import {
|
|
type ChatSummary,
|
|
ChatSummariesSchema,
|
|
type UserSettings,
|
|
} from "../lib/schemas";
|
|
import type {
|
|
App,
|
|
AppOutput,
|
|
Chat,
|
|
ChatResponseEnd,
|
|
CreateAppParams,
|
|
CreateAppResult,
|
|
ListAppsResponse,
|
|
NodeSystemInfo,
|
|
Message,
|
|
Version,
|
|
SystemDebugInfo,
|
|
LocalModel,
|
|
TokenCountParams,
|
|
TokenCountResult,
|
|
ChatLogsData,
|
|
BranchResult,
|
|
LanguageModelProvider,
|
|
LanguageModel,
|
|
CreateCustomLanguageModelProviderParams,
|
|
CreateCustomLanguageModelParams,
|
|
DoesReleaseNoteExistParams,
|
|
ApproveProposalResult,
|
|
ImportAppResult,
|
|
ImportAppParams,
|
|
RenameBranchParams,
|
|
} from "./ipc_types";
|
|
import type { ProposalResult } from "@/lib/schemas";
|
|
import { showError } from "@/lib/toast";
|
|
|
|
export interface ChatStreamCallbacks {
|
|
onUpdate: (messages: Message[]) => void;
|
|
onEnd: (response: ChatResponseEnd) => void;
|
|
onError: (error: string) => void;
|
|
}
|
|
|
|
export interface AppStreamCallbacks {
|
|
onOutput: (output: AppOutput) => void;
|
|
}
|
|
|
|
export interface GitHubDeviceFlowUpdateData {
|
|
userCode?: string;
|
|
verificationUri?: string;
|
|
message?: string;
|
|
}
|
|
|
|
export interface GitHubDeviceFlowSuccessData {
|
|
message?: string;
|
|
}
|
|
|
|
export interface GitHubDeviceFlowErrorData {
|
|
error: string;
|
|
}
|
|
|
|
export interface DeepLinkData {
|
|
type: string;
|
|
url?: string;
|
|
}
|
|
|
|
interface DeleteCustomModelParams {
|
|
providerId: string;
|
|
modelApiName: string;
|
|
}
|
|
|
|
export class IpcClient {
|
|
private static instance: IpcClient;
|
|
private ipcRenderer: IpcRenderer;
|
|
private chatStreams: Map<number, ChatStreamCallbacks>;
|
|
private appStreams: Map<number, AppStreamCallbacks>;
|
|
private constructor() {
|
|
this.ipcRenderer = (window as any).electron.ipcRenderer as IpcRenderer;
|
|
this.chatStreams = new Map();
|
|
this.appStreams = new Map();
|
|
// Set up listeners for stream events
|
|
this.ipcRenderer.on("chat:response:chunk", (data) => {
|
|
if (
|
|
data &&
|
|
typeof data === "object" &&
|
|
"chatId" in data &&
|
|
"messages" in data
|
|
) {
|
|
const { chatId, messages } = data as {
|
|
chatId: number;
|
|
messages: Message[];
|
|
};
|
|
|
|
const callbacks = this.chatStreams.get(chatId);
|
|
if (callbacks) {
|
|
callbacks.onUpdate(messages);
|
|
} else {
|
|
console.warn(
|
|
`[IPC] No callbacks found for chat ${chatId}`,
|
|
this.chatStreams,
|
|
);
|
|
}
|
|
} else {
|
|
showError(new Error(`[IPC] Invalid chunk data received: ${data}`));
|
|
}
|
|
});
|
|
|
|
this.ipcRenderer.on("app:output", (data) => {
|
|
if (
|
|
data &&
|
|
typeof data === "object" &&
|
|
"type" in data &&
|
|
"message" in data &&
|
|
"appId" in data
|
|
) {
|
|
const { type, message, appId } = data as unknown as AppOutput;
|
|
const callbacks = this.appStreams.get(appId);
|
|
if (callbacks) {
|
|
callbacks.onOutput({ type, message, appId, timestamp: Date.now() });
|
|
}
|
|
} else {
|
|
showError(new Error(`[IPC] Invalid app output data received: ${data}`));
|
|
}
|
|
});
|
|
|
|
this.ipcRenderer.on("chat:response:end", (payload) => {
|
|
const { chatId } = payload as unknown as ChatResponseEnd;
|
|
const callbacks = this.chatStreams.get(chatId);
|
|
if (callbacks) {
|
|
callbacks.onEnd(payload as unknown as ChatResponseEnd);
|
|
console.debug("chat:response:end");
|
|
this.chatStreams.delete(chatId);
|
|
} else {
|
|
console.error(
|
|
new Error(
|
|
`[IPC] No callbacks found for chat ${chatId} on stream end`,
|
|
),
|
|
);
|
|
}
|
|
});
|
|
|
|
this.ipcRenderer.on("chat:response:error", (error) => {
|
|
console.debug("chat:response:error");
|
|
if (typeof error === "string") {
|
|
for (const [chatId, callbacks] of this.chatStreams.entries()) {
|
|
callbacks.onError(error);
|
|
this.chatStreams.delete(chatId);
|
|
}
|
|
} else {
|
|
console.error("[IPC] Invalid error data received:", error);
|
|
}
|
|
});
|
|
}
|
|
|
|
public static getInstance(): IpcClient {
|
|
if (!IpcClient.instance) {
|
|
IpcClient.instance = new IpcClient();
|
|
}
|
|
return IpcClient.instance;
|
|
}
|
|
|
|
public async reloadEnvPath(): Promise<void> {
|
|
await this.ipcRenderer.invoke("reload-env-path");
|
|
}
|
|
|
|
// Create a new app with an initial chat
|
|
public async createApp(params: CreateAppParams): Promise<CreateAppResult> {
|
|
return this.ipcRenderer.invoke("create-app", params);
|
|
}
|
|
|
|
public async getApp(appId: number): Promise<App> {
|
|
return this.ipcRenderer.invoke("get-app", appId);
|
|
}
|
|
|
|
public async getChat(chatId: number): Promise<Chat> {
|
|
try {
|
|
const data = await this.ipcRenderer.invoke("get-chat", chatId);
|
|
return data;
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Get all chats
|
|
public async getChats(appId?: number): Promise<ChatSummary[]> {
|
|
try {
|
|
const data = await this.ipcRenderer.invoke("get-chats", appId);
|
|
return ChatSummariesSchema.parse(data);
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Get all apps
|
|
public async listApps(): Promise<ListAppsResponse> {
|
|
return this.ipcRenderer.invoke("list-apps");
|
|
}
|
|
|
|
public async readAppFile(appId: number, filePath: string): Promise<string> {
|
|
return this.ipcRenderer.invoke("read-app-file", {
|
|
appId,
|
|
filePath,
|
|
});
|
|
}
|
|
|
|
// Edit a file in an app directory
|
|
public async editAppFile(
|
|
appId: number,
|
|
filePath: string,
|
|
content: string,
|
|
): Promise<void> {
|
|
await this.ipcRenderer.invoke("edit-app-file", {
|
|
appId,
|
|
filePath,
|
|
content,
|
|
});
|
|
}
|
|
|
|
// New method for streaming responses
|
|
public streamMessage(
|
|
prompt: string,
|
|
options: {
|
|
chatId: number;
|
|
redo?: boolean;
|
|
attachments?: File[];
|
|
onUpdate: (messages: Message[]) => void;
|
|
onEnd: (response: ChatResponseEnd) => void;
|
|
onError: (error: string) => void;
|
|
},
|
|
): void {
|
|
const { chatId, redo, attachments, onUpdate, onEnd, onError } = options;
|
|
this.chatStreams.set(chatId, { onUpdate, onEnd, onError });
|
|
|
|
// Handle file attachments if provided
|
|
if (attachments && attachments.length > 0) {
|
|
// Process each file and convert to base64
|
|
Promise.all(
|
|
attachments.map(async (file) => {
|
|
return new Promise<{ name: string; type: string; data: string }>(
|
|
(resolve, reject) => {
|
|
const reader = new FileReader();
|
|
reader.onload = () => {
|
|
resolve({
|
|
name: file.name,
|
|
type: file.type,
|
|
data: reader.result as string,
|
|
});
|
|
};
|
|
reader.onerror = () =>
|
|
reject(new Error(`Failed to read file: ${file.name}`));
|
|
reader.readAsDataURL(file);
|
|
},
|
|
);
|
|
}),
|
|
)
|
|
.then((fileDataArray) => {
|
|
// Use invoke to start the stream and pass the chatId and attachments
|
|
this.ipcRenderer
|
|
.invoke("chat:stream", {
|
|
prompt,
|
|
chatId,
|
|
redo,
|
|
attachments: fileDataArray,
|
|
})
|
|
.catch((err) => {
|
|
showError(err);
|
|
onError(String(err));
|
|
this.chatStreams.delete(chatId);
|
|
});
|
|
})
|
|
.catch((err) => {
|
|
showError(err);
|
|
onError(String(err));
|
|
this.chatStreams.delete(chatId);
|
|
});
|
|
} else {
|
|
// No attachments, proceed normally
|
|
this.ipcRenderer
|
|
.invoke("chat:stream", {
|
|
prompt,
|
|
chatId,
|
|
redo,
|
|
})
|
|
.catch((err) => {
|
|
showError(err);
|
|
onError(String(err));
|
|
this.chatStreams.delete(chatId);
|
|
});
|
|
}
|
|
}
|
|
|
|
// Method to cancel an ongoing stream
|
|
public cancelChatStream(chatId: number): void {
|
|
this.ipcRenderer.invoke("chat:cancel", chatId);
|
|
const callbacks = this.chatStreams.get(chatId);
|
|
if (callbacks) {
|
|
this.chatStreams.delete(chatId);
|
|
} else {
|
|
console.error("Tried canceling chat that doesn't exist");
|
|
}
|
|
}
|
|
|
|
// Create a new chat for an app
|
|
public async createChat(appId: number): Promise<number> {
|
|
return this.ipcRenderer.invoke("create-chat", appId);
|
|
}
|
|
|
|
public async deleteChat(chatId: number): Promise<void> {
|
|
await this.ipcRenderer.invoke("delete-chat", chatId);
|
|
}
|
|
|
|
public async deleteMessages(chatId: number): Promise<void> {
|
|
await this.ipcRenderer.invoke("delete-messages", chatId);
|
|
}
|
|
|
|
// Open an external URL using the default browser
|
|
public async openExternalUrl(url: string): Promise<void> {
|
|
await this.ipcRenderer.invoke("open-external-url", url);
|
|
}
|
|
|
|
public async showItemInFolder(fullPath: string): Promise<void> {
|
|
await this.ipcRenderer.invoke("show-item-in-folder", fullPath);
|
|
}
|
|
|
|
// Run an app
|
|
public async runApp(
|
|
appId: number,
|
|
onOutput: (output: AppOutput) => void,
|
|
): Promise<void> {
|
|
await this.ipcRenderer.invoke("run-app", { appId });
|
|
this.appStreams.set(appId, { onOutput });
|
|
}
|
|
|
|
// Stop a running app
|
|
public async stopApp(appId: number): Promise<void> {
|
|
await this.ipcRenderer.invoke("stop-app", { appId });
|
|
}
|
|
|
|
// Restart a running app
|
|
public async restartApp(
|
|
appId: number,
|
|
onOutput: (output: AppOutput) => void,
|
|
removeNodeModules?: boolean,
|
|
): Promise<{ success: boolean }> {
|
|
try {
|
|
const result = await this.ipcRenderer.invoke("restart-app", {
|
|
appId,
|
|
removeNodeModules,
|
|
});
|
|
this.appStreams.set(appId, { onOutput });
|
|
return result;
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Get allow-listed environment variables
|
|
public async getEnvVars(): Promise<Record<string, string | undefined>> {
|
|
try {
|
|
const envVars = await this.ipcRenderer.invoke("get-env-vars");
|
|
return envVars as Record<string, string | undefined>;
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// List all versions (commits) of an app
|
|
public async listVersions({ appId }: { appId: number }): Promise<Version[]> {
|
|
try {
|
|
const versions = await this.ipcRenderer.invoke("list-versions", {
|
|
appId,
|
|
});
|
|
return versions;
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Revert to a specific version
|
|
public async revertVersion({
|
|
appId,
|
|
previousVersionId,
|
|
}: {
|
|
appId: number;
|
|
previousVersionId: string;
|
|
}): Promise<void> {
|
|
await this.ipcRenderer.invoke("revert-version", {
|
|
appId,
|
|
previousVersionId,
|
|
});
|
|
}
|
|
|
|
// Checkout a specific version without creating a revert commit
|
|
public async checkoutVersion({
|
|
appId,
|
|
versionId,
|
|
}: {
|
|
appId: number;
|
|
versionId: string;
|
|
}): Promise<void> {
|
|
await this.ipcRenderer.invoke("checkout-version", {
|
|
appId,
|
|
versionId,
|
|
});
|
|
}
|
|
|
|
// Get the current branch of an app
|
|
public async getCurrentBranch(appId: number): Promise<BranchResult> {
|
|
return this.ipcRenderer.invoke("get-current-branch", {
|
|
appId,
|
|
});
|
|
}
|
|
|
|
// Get user settings
|
|
public async getUserSettings(): Promise<UserSettings> {
|
|
try {
|
|
const settings = await this.ipcRenderer.invoke("get-user-settings");
|
|
return settings;
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Update user settings
|
|
public async setUserSettings(
|
|
settings: Partial<UserSettings>,
|
|
): Promise<UserSettings> {
|
|
try {
|
|
const updatedSettings = await this.ipcRenderer.invoke(
|
|
"set-user-settings",
|
|
settings,
|
|
);
|
|
return updatedSettings;
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Delete an app and all its files
|
|
public async deleteApp(appId: number): Promise<void> {
|
|
await this.ipcRenderer.invoke("delete-app", { appId });
|
|
}
|
|
|
|
// Rename an app (update name and path)
|
|
public async renameApp({
|
|
appId,
|
|
appName,
|
|
appPath,
|
|
}: {
|
|
appId: number;
|
|
appName: string;
|
|
appPath: string;
|
|
}): Promise<void> {
|
|
await this.ipcRenderer.invoke("rename-app", {
|
|
appId,
|
|
appName,
|
|
appPath,
|
|
});
|
|
}
|
|
|
|
// Reset all - removes all app files, settings, and drops the database
|
|
public async resetAll(): Promise<void> {
|
|
await this.ipcRenderer.invoke("reset-all");
|
|
}
|
|
|
|
public async addDependency({
|
|
chatId,
|
|
packages,
|
|
}: {
|
|
chatId: number;
|
|
packages: string[];
|
|
}): Promise<void> {
|
|
await this.ipcRenderer.invoke("chat:add-dep", {
|
|
chatId,
|
|
packages,
|
|
});
|
|
}
|
|
|
|
// Check Node.js and npm status
|
|
public async getNodejsStatus(): Promise<NodeSystemInfo> {
|
|
return this.ipcRenderer.invoke("nodejs-status");
|
|
}
|
|
|
|
// --- GitHub Device Flow ---
|
|
public startGithubDeviceFlow(appId: number | null): void {
|
|
this.ipcRenderer.invoke("github:start-flow", { appId });
|
|
}
|
|
|
|
public onGithubDeviceFlowUpdate(
|
|
callback: (data: GitHubDeviceFlowUpdateData) => void,
|
|
): () => void {
|
|
const listener = (data: any) => {
|
|
console.log("github:flow-update", data);
|
|
callback(data as GitHubDeviceFlowUpdateData);
|
|
};
|
|
this.ipcRenderer.on("github:flow-update", listener);
|
|
// Return a function to remove the listener
|
|
return () => {
|
|
this.ipcRenderer.removeListener("github:flow-update", listener);
|
|
};
|
|
}
|
|
|
|
public onGithubDeviceFlowSuccess(
|
|
callback: (data: GitHubDeviceFlowSuccessData) => void,
|
|
): () => void {
|
|
const listener = (data: any) => {
|
|
console.log("github:flow-success", data);
|
|
callback(data as GitHubDeviceFlowSuccessData);
|
|
};
|
|
this.ipcRenderer.on("github:flow-success", listener);
|
|
return () => {
|
|
this.ipcRenderer.removeListener("github:flow-success", listener);
|
|
};
|
|
}
|
|
|
|
public onGithubDeviceFlowError(
|
|
callback: (data: GitHubDeviceFlowErrorData) => void,
|
|
): () => void {
|
|
const listener = (data: any) => {
|
|
console.log("github:flow-error", data);
|
|
callback(data as GitHubDeviceFlowErrorData);
|
|
};
|
|
this.ipcRenderer.on("github:flow-error", listener);
|
|
return () => {
|
|
this.ipcRenderer.removeListener("github:flow-error", listener);
|
|
};
|
|
}
|
|
// --- End GitHub Device Flow ---
|
|
|
|
// --- GitHub Repo Management ---
|
|
public async checkGithubRepoAvailable(
|
|
org: string,
|
|
repo: string,
|
|
): Promise<{ available: boolean; error?: string }> {
|
|
return this.ipcRenderer.invoke("github:is-repo-available", {
|
|
org,
|
|
repo,
|
|
});
|
|
}
|
|
|
|
public async createGithubRepo(
|
|
org: string,
|
|
repo: string,
|
|
appId: number,
|
|
): Promise<void> {
|
|
await this.ipcRenderer.invoke("github:create-repo", {
|
|
org,
|
|
repo,
|
|
appId,
|
|
});
|
|
}
|
|
|
|
// Sync (push) local repo to GitHub
|
|
public async syncGithubRepo(
|
|
appId: number,
|
|
): Promise<{ success: boolean; error?: string }> {
|
|
try {
|
|
const result = await this.ipcRenderer.invoke("github:push", { appId });
|
|
return result as { success: boolean; error?: string };
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
public async disconnectGithubRepo(appId: number): Promise<void> {
|
|
await this.ipcRenderer.invoke("github:disconnect", {
|
|
appId,
|
|
});
|
|
}
|
|
// --- End GitHub Repo Management ---
|
|
|
|
// Get the main app version
|
|
public async getAppVersion(): Promise<string> {
|
|
const result = await this.ipcRenderer.invoke("get-app-version");
|
|
return result.version as string;
|
|
}
|
|
|
|
// Get proposal details
|
|
public async getProposal(chatId: number): Promise<ProposalResult | null> {
|
|
try {
|
|
const data = await this.ipcRenderer.invoke("get-proposal", { chatId });
|
|
// Assuming the main process returns data matching the ProposalResult interface
|
|
// Add a type check/guard if necessary for robustness
|
|
return data as ProposalResult | null;
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Example methods for listening to events (if needed)
|
|
// public on(channel: string, func: (...args: any[]) => void): void {
|
|
|
|
// --- Proposal Management ---
|
|
public async approveProposal({
|
|
chatId,
|
|
messageId,
|
|
}: {
|
|
chatId: number;
|
|
messageId: number;
|
|
}): Promise<ApproveProposalResult> {
|
|
return this.ipcRenderer.invoke("approve-proposal", {
|
|
chatId,
|
|
messageId,
|
|
});
|
|
}
|
|
|
|
public async rejectProposal({
|
|
chatId,
|
|
messageId,
|
|
}: {
|
|
chatId: number;
|
|
messageId: number;
|
|
}): Promise<void> {
|
|
await this.ipcRenderer.invoke("reject-proposal", {
|
|
chatId,
|
|
messageId,
|
|
});
|
|
}
|
|
// --- End Proposal Management ---
|
|
|
|
// --- Supabase Management ---
|
|
public async listSupabaseProjects(): Promise<any[]> {
|
|
return this.ipcRenderer.invoke("supabase:list-projects");
|
|
}
|
|
|
|
public async setSupabaseAppProject(
|
|
project: string,
|
|
app: number,
|
|
): Promise<void> {
|
|
await this.ipcRenderer.invoke("supabase:set-app-project", {
|
|
project,
|
|
app,
|
|
});
|
|
}
|
|
|
|
public async unsetSupabaseAppProject(app: number): Promise<void> {
|
|
await this.ipcRenderer.invoke("supabase:unset-app-project", {
|
|
app,
|
|
});
|
|
}
|
|
// --- End Supabase Management ---
|
|
|
|
public async getSystemDebugInfo(): Promise<SystemDebugInfo> {
|
|
return this.ipcRenderer.invoke("get-system-debug-info");
|
|
}
|
|
|
|
public async getChatLogs(chatId: number): Promise<ChatLogsData> {
|
|
return this.ipcRenderer.invoke("get-chat-logs", chatId);
|
|
}
|
|
|
|
public async uploadToSignedUrl(
|
|
url: string,
|
|
contentType: string,
|
|
data: any,
|
|
): Promise<void> {
|
|
await this.ipcRenderer.invoke("upload-to-signed-url", {
|
|
url,
|
|
contentType,
|
|
data,
|
|
});
|
|
}
|
|
|
|
public async listLocalOllamaModels(): Promise<LocalModel[]> {
|
|
const response = await this.ipcRenderer.invoke("local-models:list-ollama");
|
|
return response?.models || [];
|
|
}
|
|
|
|
public async listLocalLMStudioModels(): Promise<LocalModel[]> {
|
|
const response = await this.ipcRenderer.invoke(
|
|
"local-models:list-lmstudio",
|
|
);
|
|
return response?.models || [];
|
|
}
|
|
|
|
// Listen for deep link events
|
|
public onDeepLinkReceived(
|
|
callback: (data: DeepLinkData) => void,
|
|
): () => void {
|
|
const listener = (data: any) => {
|
|
callback(data as DeepLinkData);
|
|
};
|
|
this.ipcRenderer.on("deep-link-received", listener);
|
|
return () => {
|
|
this.ipcRenderer.removeListener("deep-link-received", listener);
|
|
};
|
|
}
|
|
|
|
// Count tokens for a chat and input
|
|
public async countTokens(
|
|
params: TokenCountParams,
|
|
): Promise<TokenCountResult> {
|
|
try {
|
|
const result = await this.ipcRenderer.invoke("chat:count-tokens", params);
|
|
return result as TokenCountResult;
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Window control methods
|
|
public async minimizeWindow(): Promise<void> {
|
|
try {
|
|
await this.ipcRenderer.invoke("window:minimize");
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
public async maximizeWindow(): Promise<void> {
|
|
try {
|
|
await this.ipcRenderer.invoke("window:maximize");
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
public async closeWindow(): Promise<void> {
|
|
try {
|
|
await this.ipcRenderer.invoke("window:close");
|
|
} catch (error) {
|
|
showError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Get system platform (win32, darwin, linux)
|
|
public async getSystemPlatform(): Promise<string> {
|
|
return this.ipcRenderer.invoke("get-system-platform");
|
|
}
|
|
|
|
public async doesReleaseNoteExist(
|
|
params: DoesReleaseNoteExistParams,
|
|
): Promise<{ exists: boolean; url?: string }> {
|
|
return this.ipcRenderer.invoke("does-release-note-exist", params);
|
|
}
|
|
|
|
public async getLanguageModelProviders(): Promise<LanguageModelProvider[]> {
|
|
return this.ipcRenderer.invoke("get-language-model-providers");
|
|
}
|
|
|
|
public async getLanguageModels(params: {
|
|
providerId: string;
|
|
}): Promise<LanguageModel[]> {
|
|
return this.ipcRenderer.invoke("get-language-models", params);
|
|
}
|
|
|
|
public async getLanguageModelsByProviders(): Promise<
|
|
Record<string, LanguageModel[]>
|
|
> {
|
|
return this.ipcRenderer.invoke("get-language-models-by-providers");
|
|
}
|
|
|
|
public async createCustomLanguageModelProvider({
|
|
id,
|
|
name,
|
|
apiBaseUrl,
|
|
envVarName,
|
|
}: CreateCustomLanguageModelProviderParams): Promise<LanguageModelProvider> {
|
|
return this.ipcRenderer.invoke("create-custom-language-model-provider", {
|
|
id,
|
|
name,
|
|
apiBaseUrl,
|
|
envVarName,
|
|
});
|
|
}
|
|
|
|
public async createCustomLanguageModel(
|
|
params: CreateCustomLanguageModelParams,
|
|
): Promise<void> {
|
|
await this.ipcRenderer.invoke("create-custom-language-model", params);
|
|
}
|
|
|
|
public async deleteCustomLanguageModel(modelId: string): Promise<void> {
|
|
return this.ipcRenderer.invoke("delete-custom-language-model", modelId);
|
|
}
|
|
|
|
async deleteCustomModel(params: DeleteCustomModelParams): Promise<void> {
|
|
return this.ipcRenderer.invoke("delete-custom-model", params);
|
|
}
|
|
|
|
async deleteCustomLanguageModelProvider(providerId: string): Promise<void> {
|
|
return this.ipcRenderer.invoke("delete-custom-language-model-provider", {
|
|
providerId,
|
|
});
|
|
}
|
|
|
|
public async selectAppFolder(): Promise<{
|
|
path: string | null;
|
|
name: string | null;
|
|
}> {
|
|
return this.ipcRenderer.invoke("select-app-folder");
|
|
}
|
|
|
|
public async checkAiRules(params: {
|
|
path: string;
|
|
}): Promise<{ exists: boolean }> {
|
|
return this.ipcRenderer.invoke("check-ai-rules", params);
|
|
}
|
|
|
|
public async importApp(params: ImportAppParams): Promise<ImportAppResult> {
|
|
return this.ipcRenderer.invoke("import-app", params);
|
|
}
|
|
|
|
async checkAppName(params: {
|
|
appName: string;
|
|
}): Promise<{ exists: boolean }> {
|
|
return this.ipcRenderer.invoke("check-app-name", params);
|
|
}
|
|
|
|
public async renameBranch(params: RenameBranchParams): Promise<void> {
|
|
await this.ipcRenderer.invoke("rename-branch", params);
|
|
}
|
|
|
|
async clearSessionData(): Promise<void> {
|
|
return this.ipcRenderer.invoke("clear-session-data");
|
|
}
|
|
}
|