feat(ui): Add React based UI for the vibes at /app
This adds a completely separate frontend based on React because I found that code gen works better with React once the application gets bigger. In particular it was getting very hard to move past add connectors and actions. The idea is to replace the standard UI with this once it has been tested. But for now it is available at /app in addition to the original at / Signed-off-by: Richard Palethorpe <io@richiejp.com>
This commit is contained in:
198
webui/react-ui/src/utils/api.js
vendored
Normal file
198
webui/react-ui/src/utils/api.js
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* API utility for communicating with the Go backend
|
||||
*/
|
||||
import { API_CONFIG } from './config';
|
||||
|
||||
// Helper function for handling API responses
|
||||
const handleResponse = async (response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.error || `API error: ${response.status}`);
|
||||
}
|
||||
|
||||
// Check if response is JSON
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (contentType && contentType.includes('application/json')) {
|
||||
return response.json();
|
||||
}
|
||||
|
||||
return response.text();
|
||||
};
|
||||
|
||||
// Helper function to build a full URL
|
||||
const buildUrl = (endpoint) => {
|
||||
return `${API_CONFIG.baseUrl}${endpoint.startsWith('/') ? endpoint.substring(1) : endpoint}`;
|
||||
};
|
||||
|
||||
// Agent-related API calls
|
||||
export const agentApi = {
|
||||
// Get list of all agents
|
||||
getAgents: async () => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.agents), {
|
||||
headers: API_CONFIG.headers
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Get a specific agent's configuration
|
||||
getAgentConfig: async (name) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.agentConfig(name)), {
|
||||
headers: API_CONFIG.headers
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Create a new agent
|
||||
createAgent: async (config) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.createAgent), {
|
||||
method: 'POST',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify(config),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Update an existing agent's configuration
|
||||
updateAgentConfig: async (name, config) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.agentConfig(name)), {
|
||||
method: 'PUT',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify(config),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Delete an agent
|
||||
deleteAgent: async (name) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.deleteAgent(name)), {
|
||||
method: 'DELETE',
|
||||
headers: API_CONFIG.headers,
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Pause an agent
|
||||
pauseAgent: async (name) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.pauseAgent(name)), {
|
||||
method: 'PUT',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Start an agent
|
||||
startAgent: async (name) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.startAgent(name)), {
|
||||
method: 'PUT',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Export agent configuration
|
||||
exportAgentConfig: async (name) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.exportAgent(name)), {
|
||||
headers: API_CONFIG.headers
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Import agent configuration
|
||||
importAgentConfig: async (configData) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.importAgent), {
|
||||
method: 'POST',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify(configData),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Generate group profiles
|
||||
generateGroupProfiles: async (data) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.generateGroupProfiles), {
|
||||
method: 'POST',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Create a group of agents
|
||||
createGroup: async (data) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.createGroup), {
|
||||
method: 'POST',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
};
|
||||
|
||||
// Chat-related API calls
|
||||
export const chatApi = {
|
||||
// Send a chat message to an agent
|
||||
sendMessage: async (name, message) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.chat(name)), {
|
||||
method: 'POST',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify({ message }),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Send a notification to an agent
|
||||
sendNotification: async (name, message) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.notify(name)), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({ message }),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Get responses from an agent
|
||||
getResponses: async (data) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.responses), {
|
||||
method: 'POST',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
};
|
||||
|
||||
// Action-related API calls
|
||||
export const actionApi = {
|
||||
// List available actions
|
||||
listActions: async () => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.listActions), {
|
||||
headers: API_CONFIG.headers
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
|
||||
// Execute an action for an agent
|
||||
executeAction: async (name, actionData) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.executeAction(name)), {
|
||||
method: 'POST',
|
||||
headers: API_CONFIG.headers,
|
||||
body: JSON.stringify(actionData),
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
};
|
||||
|
||||
// Status-related API calls
|
||||
export const statusApi = {
|
||||
// Get agent status history
|
||||
getStatusHistory: async (name) => {
|
||||
const response = await fetch(buildUrl(API_CONFIG.endpoints.status(name)), {
|
||||
headers: API_CONFIG.headers
|
||||
});
|
||||
return handleResponse(response);
|
||||
},
|
||||
};
|
||||
49
webui/react-ui/src/utils/config.js
vendored
Normal file
49
webui/react-ui/src/utils/config.js
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Application configuration
|
||||
*/
|
||||
|
||||
// Get the base URL from Vite's environment variables or default to '/app/'
|
||||
export const BASE_URL = import.meta.env.BASE_URL || '/app/';
|
||||
|
||||
// API endpoints configuration
|
||||
export const API_CONFIG = {
|
||||
// Base URL for API requests
|
||||
baseUrl: '/', // API endpoints are at the root, not under /app/
|
||||
|
||||
// Default headers for API requests
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
|
||||
// Endpoints
|
||||
endpoints: {
|
||||
// Agent endpoints
|
||||
agents: '/api/agents',
|
||||
agentConfig: (name) => `/api/agent/${name}/config`,
|
||||
createAgent: '/create',
|
||||
deleteAgent: (name) => `/delete/${name}`,
|
||||
pauseAgent: (name) => `/pause/${name}`,
|
||||
startAgent: (name) => `/start/${name}`,
|
||||
exportAgent: (name) => `/settings/export/${name}`,
|
||||
importAgent: '/settings/import',
|
||||
|
||||
// Group endpoints
|
||||
generateGroupProfiles: '/api/agent/group/generateProfiles',
|
||||
createGroup: '/api/agent/group/create',
|
||||
|
||||
// Chat endpoints
|
||||
chat: (name) => `/chat/${name}`,
|
||||
notify: (name) => `/notify/${name}`,
|
||||
responses: '/v1/responses',
|
||||
|
||||
// SSE endpoint
|
||||
sse: (name) => `/sse/${name}`,
|
||||
|
||||
// Action endpoints
|
||||
listActions: '/actions',
|
||||
executeAction: (name) => `/action/${name}/run`,
|
||||
|
||||
// Status endpoint
|
||||
status: (name) => `/status/${name}`,
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user