feat: add standalone ops ai workspace setup

This commit is contained in:
DCCONSTRUCTIONS
2026-06-09 13:23:02 +03:00
parent 6c119aae04
commit 71979526cf
6 changed files with 810 additions and 63 deletions
@@ -8,17 +8,24 @@ import { API_BASE_URL } from "@plane/constants";
import { APIService } from "@/services/api.service";
export type TAIWorkspaceExecutorStatus = "unknown" | "online" | "offline" | "checking" | "error";
export type TAIWorkspaceExecutorConnectionMode = "hub" | "direct";
export type TAIWorkspaceExecutor = {
id: string;
name: string;
type: string;
connectionMode: "hub" | "direct";
connectionMode: TAIWorkspaceExecutorConnectionMode;
endpoint?: string | null;
workspacePath?: string | null;
agentPort?: number | null;
pairingCode?: string | null;
model?: string | null;
accountLabel?: string | null;
capabilities?: string[];
status: TAIWorkspaceExecutorStatus;
statusDetail?: string | null;
lastSeenAt?: string | null;
createdAt?: string | null;
updatedAt?: string | null;
};
@@ -28,6 +35,21 @@ export type TAIWorkspaceExecutorListResponse = {
executors: TAIWorkspaceExecutor[];
};
export type TAIWorkspaceExecutorInput = {
id?: string;
name: string;
type?: string;
connectionMode?: TAIWorkspaceExecutorConnectionMode;
endpoint?: string | null;
workspacePath?: string | null;
agentPort?: number | null;
pairingCode?: string | null;
model?: string | null;
accountLabel?: string | null;
capabilities?: string[];
status?: TAIWorkspaceExecutorStatus;
};
export class WorkspaceAIWorkspaceService extends APIService {
constructor() {
super(API_BASE_URL);
@@ -40,4 +62,43 @@ export class WorkspaceAIWorkspaceService extends APIService {
throw error?.response?.data ?? error;
});
}
async createExecutor(workspaceSlug: string, input: TAIWorkspaceExecutorInput): Promise<TAIWorkspaceExecutorListResponse> {
await this.post(`/api/workspaces/${workspaceSlug}/ai-workspace/executors/`, { ...input, select: true }).catch((error) => {
throw error?.response?.data ?? error;
});
return this.listExecutors(workspaceSlug);
}
async updateExecutor(
workspaceSlug: string,
executorId: string,
input: Partial<TAIWorkspaceExecutorInput>
): Promise<TAIWorkspaceExecutorListResponse> {
await this.patch(`/api/workspaces/${workspaceSlug}/ai-workspace/executors/${executorId}/`, input).catch((error) => {
throw error?.response?.data ?? error;
});
return this.listExecutors(workspaceSlug);
}
async deleteExecutor(workspaceSlug: string, executorId: string): Promise<TAIWorkspaceExecutorListResponse> {
await this.delete(`/api/workspaces/${workspaceSlug}/ai-workspace/executors/${executorId}/`).catch((error) => {
throw error?.response?.data ?? error;
});
return this.listExecutors(workspaceSlug);
}
async selectExecutor(workspaceSlug: string, executorId: string): Promise<TAIWorkspaceExecutorListResponse> {
await this.post(`/api/workspaces/${workspaceSlug}/ai-workspace/executors/${executorId}/select/`).catch((error) => {
throw error?.response?.data ?? error;
});
return this.listExecutors(workspaceSlug);
}
getWindowsAgentInstallerUrl(workspaceSlug: string, executorId: string, options: { port?: string | number } = {}) {
const params = new URLSearchParams({ v: `${Date.now()}` });
const port = String(options.port || "").trim();
if (port) params.set("port", port);
return `${API_BASE_URL}/api/workspaces/${workspaceSlug}/ai-workspace/executors/${executorId}/agent/windows.ps1?${params.toString()}`;
}
}