import { fetchWithAuth, getUserId } from './apiClient';
/**
* [USER] List nodes accessible to the current user's group.
*/
export const getUserAccessibleNodes = async () => {
const userId = getUserId();
return await fetchWithAuth(`/nodes/?user_id=${userId}`);
};
/**
* [USER] Fetch node preferences.
*/
export const getUserNodePreferences = async () => {
const userId = getUserId();
return await fetchWithAuth(`/nodes/preferences?user_id=${userId}`);
};
/**
* [USER] Update node preferences.
*/
export const updateUserNodePreferences = async (prefs) => {
const userId = getUserId();
return await fetchWithAuth(`/nodes/preferences?user_id=${userId}`, {
method: "PATCH",
body: prefs
});
};
/**
* [USER] Fetch sync status for all nodes attached to a session.
*/
export const getSessionNodeStatus = async (sessionId) => {
return await fetchWithAuth(`/sessions/${sessionId}/nodes`);
};
/**
* [USER] Attach more nodes to an active session.
*/
export const attachNodesToSession = async (sessionId, nodeIds, config = null) => {
return await fetchWithAuth(`/sessions/${sessionId}/nodes`, {
method: "POST",
body: { node_ids: nodeIds, config }
});
};
/**
* [USER] Detach a node from a session.
*/
export const detachNodeFromSession = async (sessionId, nodeId) => {
return await fetchWithAuth(`/sessions/${sessionId}/nodes/${nodeId}`, {
method: "DELETE"
});
};
/**
* [AI Observability] Fetch terminal history for a node.
*/
export const getNodeTerminalHistory = async (nodeId) => {
return await fetchWithAuth(`/nodes/${nodeId}/terminal`);
};
/**
* Dispatch a task to a node.
*/
export const dispatchNodeTask = async (nodeId, payload) => {
return await fetchWithAuth(`/nodes/${nodeId}/dispatch`, {
method: 'POST',
body: payload
});
};
/**
* Cancel a task on a node.
*/
export const cancelNodeTask = async (nodeId, taskId = "") => {
return await fetchWithAuth(`/nodes/${nodeId}/cancel?task_id=${taskId}`, {
method: 'POST'
});
};
/**
* WebSocket helper for live node streams.
*/
export const getNodeStreamUrl = (nodeId = null) => {
const { API_BASE_URL } = require('./apiClient');
// Convert http://... to ws://...
const wsBase = API_BASE_URL.replace(/^http/, 'ws');
if (nodeId) {
const userId = getUserId();
return `${wsBase}/nodes/${nodeId}/stream?user_id=${userId}`;
}
const userId = localStorage.getItem('userId');
return `${wsBase}/nodes/stream/all?user_id=${userId}`;
};
/**
* [FS] List directory contents on an agent node.
*/
export const nodeFsList = async (nodeId, path = ".", sessionId = null) => {
const params = new URLSearchParams({ path });
if (sessionId) params.append("session_id", sessionId);
return await fetchWithAuth(`/nodes/${nodeId}/fs/ls?${params.toString()}`);
};
/**
* [FS] Read file content from an agent node.
*/
export const nodeFsCat = async (nodeId, path, sessionId = null) => {
const params = new URLSearchParams({ path });
if (sessionId) params.append("session_id", sessionId);
return await fetchWithAuth(`/nodes/${nodeId}/fs/cat?${params.toString()}`);
};
/**
* [FS] Create or update a file or directory on an agent node.
*/
export const nodeFsTouch = async (nodeId, path, content = "", isDir = false, sessionId = null) => {
return await fetchWithAuth(`/nodes/${nodeId}/fs/touch`, {
method: "POST",
body: { path, content, is_dir: isDir, session_id: sessionId }
});
};
/**
* [FS] Upload a file to an agent node via multipart form.
*/
export const nodeFsUpload = async (nodeId, path, file, sessionId = null) => {
const formData = new FormData();
formData.append("file", file);
const params = new URLSearchParams({ path });
if (sessionId) params.append("session_id", sessionId);
return await fetchWithAuth(`/nodes/${nodeId}/fs/upload?${params.toString()}`, {
method: "POST",
body: formData
});
};
/**
* [FS] Downloads a file as a blob.
*/
export const nodeFsDownloadBlob = async (nodeId, path, sessionId = null) => {
const params = new URLSearchParams({ path });
if (sessionId) params.append("session_id", sessionId);
const response = await fetchWithAuth(`/nodes/${nodeId}/fs/download?${params.toString()}`, {
method: "GET",
raw: true
});
return await response.blob();
};
/**
* [FS] Delete a file or directory from an agent node.
*/
export const nodeFsRm = async (nodeId, path, sessionId = null) => {
return await fetchWithAuth(`/nodes/${nodeId}/fs/rm`, {
method: "POST",
body: { path, session_id: sessionId }
});
};