Commit inicial - upload de todos os arquivos da pasta

This commit is contained in:
2026-01-04 16:14:31 -03:00
commit e3ed1a734b
310 changed files with 62749 additions and 0 deletions

View File

@@ -0,0 +1,238 @@
/*
┌──────────────────────────────────────────────────────────────────────────────┐
│ @author: Davidson Gomes │
│ @file: /services/agentService.ts │
│ Developed by: Davidson Gomes │
│ Creation date: May 13, 2025 │
│ Contact: contato@evolution-api.com │
├──────────────────────────────────────────────────────────────────────────────┤
│ @copyright © Evolution API 2025. All rights reserved. │
│ Licensed under the Apache License, Version 2.0 │
│ │
│ You may not use this file except in compliance with the License. │
│ You may obtain a copy of the License at │
│ │
│ http://www.apache.org/licenses/LICENSE-2.0 │
│ │
│ Unless required by applicable law or agreed to in writing, software │
│ distributed under the License is distributed on an "AS IS" BASIS, │
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
│ See the License for the specific language governing permissions and │
│ limitations under the License. │
├──────────────────────────────────────────────────────────────────────────────┤
│ @important │
│ For any future changes to the code in this file, it is recommended to │
│ include, together with the modification, the information of the developer │
│ who changed it and the date of modification. │
└──────────────────────────────────────────────────────────────────────────────┘
*/
import api from "./api";
import { Agent, AgentCreate } from "../types/agent";
import { escapePromptBraces, sanitizeAgentName } from "@/lib/utils";
const processAgentData = (data: AgentCreate | Partial<AgentCreate>): AgentCreate | Partial<AgentCreate> => {
const updatedData = {...data};
if (updatedData.instruction) {
updatedData.instruction = escapePromptBraces(updatedData.instruction);
}
if (updatedData.name) {
updatedData.name = sanitizeAgentName(updatedData.name);
}
return updatedData;
};
export const createAgent = (data: AgentCreate) =>
api.post<Agent>("/api/v1/agents/", processAgentData(data));
export const listAgents = (
clientId: string,
skip = 0,
limit = 100,
folderId?: string
) => {
const queryParams = new URLSearchParams({
skip: skip.toString(),
limit: limit.toString(),
});
if (folderId) {
queryParams.append("folder_id", folderId);
}
return api.get<Agent[]>(`/api/v1/agents/?${queryParams.toString()}`, {
headers: { "x-client-id": clientId },
});
};
export const getAgent = (agentId: string, clientId: string) =>
api.get<Agent>(`/api/v1/agents/${agentId}`, {
headers: { "x-client-id": clientId },
});
export const getSharedAgent = (agentId: string) =>
api.get<Agent>(`/api/v1/agents/${agentId}/shared`);
export const updateAgent = (agentId: string, data: Partial<AgentCreate>) =>
api.put<Agent>(`/api/v1/agents/${agentId}`, processAgentData(data));
export const deleteAgent = (agentId: string) =>
api.delete(`/api/v1/agents/${agentId}`);
// New functions for the folder system
export interface Folder {
id: string;
name: string;
description: string;
client_id: string;
created_at: string;
updated_at: string;
}
export interface FolderCreate {
name: string;
description: string;
client_id: string;
}
export interface FolderUpdate {
name?: string;
description?: string;
}
export const createFolder = (data: FolderCreate) =>
api.post<Folder>("/api/v1/agents/folders", data);
export const listFolders = (clientId: string, skip = 0, limit = 100) =>
api.get<Folder[]>(`/api/v1/agents/folders?skip=${skip}&limit=${limit}`, {
headers: { "x-client-id": clientId },
});
export const getFolder = (folderId: string, clientId: string) =>
api.get<Folder>(`/api/v1/agents/folders/${folderId}`, {
headers: { "x-client-id": clientId },
});
export const updateFolder = (
folderId: string,
data: FolderUpdate,
clientId: string
) =>
api.put<Folder>(`/api/v1/agents/folders/${folderId}`, data, {
headers: { "x-client-id": clientId },
});
export const deleteFolder = (folderId: string, clientId: string) =>
api.delete(`/api/v1/agents/folders/${folderId}`, {
headers: { "x-client-id": clientId },
});
export const listAgentsInFolder = (
folderId: string,
clientId: string,
skip = 0,
limit = 100
) =>
api.get<Agent[]>(
`/api/v1/agents/folders/${folderId}/agents?skip=${skip}&limit=${limit}`,
{
headers: { "x-client-id": clientId },
}
);
export const assignAgentToFolder = (
agentId: string,
folderId: string | null,
clientId: string
) => {
const url = folderId
? `/api/v1/agents/${agentId}/folder?folder_id=${folderId}`
: `/api/v1/agents/${agentId}/folder`;
return api.put<Agent>(
url,
{},
{
headers: { "x-client-id": clientId },
}
);
};
export const shareAgent = (agentId: string, clientId: string) =>
api.post<{ api_key: string }>(`/api/v1/agents/${agentId}/share`, {}, {
headers: { "x-client-id": clientId },
});
// API Key Interfaces and Services
export interface ApiKey {
id: string;
name: string;
provider: string;
client_id: string;
created_at: string;
updated_at: string;
is_active: boolean;
}
export interface ApiKeyCreate {
name: string;
provider: string;
client_id: string;
key_value: string;
}
export interface ApiKeyUpdate {
name?: string;
provider?: string;
key_value?: string;
is_active?: boolean;
}
export const createApiKey = (data: ApiKeyCreate) =>
api.post<ApiKey>("/api/v1/agents/apikeys", data);
export const listApiKeys = (clientId: string, skip = 0, limit = 100) =>
api.get<ApiKey[]>(`/api/v1/agents/apikeys?skip=${skip}&limit=${limit}`, {
headers: { "x-client-id": clientId },
});
export const getApiKey = (keyId: string, clientId: string) =>
api.get<ApiKey>(`/api/v1/agents/apikeys/${keyId}`, {
headers: { "x-client-id": clientId },
});
export const updateApiKey = (
keyId: string,
data: ApiKeyUpdate,
clientId: string
) =>
api.put<ApiKey>(`/api/v1/agents/apikeys/${keyId}`, data, {
headers: { "x-client-id": clientId },
});
export const deleteApiKey = (keyId: string, clientId: string) =>
api.delete(`/api/v1/agents/apikeys/${keyId}`, {
headers: { "x-client-id": clientId },
});
// Import agent from JSON file
export const importAgentFromJson = (file: File, clientId: string, folderId?: string | null) => {
const formData = new FormData();
formData.append('file', file);
// Add folder_id to formData if it exists
if (folderId) {
formData.append('folder_id', folderId);
}
return api.post('/api/v1/agents/import', formData, {
headers: {
'Content-Type': 'multipart/form-data',
'x-client-id': clientId
}
});
};

122
frontend/services/api.ts Normal file
View File

@@ -0,0 +1,122 @@
/*
┌──────────────────────────────────────────────────────────────────────────────┐
│ @author: Davidson Gomes │
│ @file: /services/api.ts │
│ Developed by: Davidson Gomes │
│ Creation date: May 13, 2025 │
│ Contact: contato@evolution-api.com │
├──────────────────────────────────────────────────────────────────────────────┤
│ @copyright © Evolution API 2025. All rights reserved. │
│ Licensed under the Apache License, Version 2.0 │
│ │
│ You may not use this file except in compliance with the License. │
│ You may obtain a copy of the License at │
│ │
│ http://www.apache.org/licenses/LICENSE-2.0 │
│ │
│ Unless required by applicable law or agreed to in writing, software │
│ distributed under the License is distributed on an "AS IS" BASIS, │
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
│ See the License for the specific language governing permissions and │
│ limitations under the License. │
├──────────────────────────────────────────────────────────────────────────────┤
│ @important │
│ For any future changes to the code in this file, it is recommended to │
│ include, together with the modification, the information of the developer │
│ who changed it and the date of modification. │
└──────────────────────────────────────────────────────────────────────────────┘
*/
import axios from "axios";
import { getApiUrl } from "@/lib/env";
const apiUrl = getApiUrl();
const api = axios.create({
baseURL: apiUrl,
headers: {
"Content-Type": "application/json",
},
});
// Flag to prevent multiple logout attempts
let isLoggingOut = false;
// Function to force logout
const forceLogout = () => {
if (isLoggingOut) return;
isLoggingOut = true;
// Clear localStorage
localStorage.removeItem("access_token");
localStorage.removeItem("user");
localStorage.removeItem("impersonatedClient");
localStorage.removeItem("isImpersonating");
// Clear cookies
document.cookie = "access_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
document.cookie = "user=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
document.cookie = "impersonatedClient=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
document.cookie = "isImpersonating=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
// Redirect to login page
window.location.href = "/login?session_expired=true";
};
// Interceptor to add the token from the cookie to the Authorization header
api.interceptors.request.use((config) => {
if (typeof window !== "undefined") {
// Verificar primeiro se estamos em uma rota de agente compartilhado
const isSharedAgentRequest = config.url && (
config.url.includes('/agents/shared') ||
config.url.includes('/chat/ws/')
);
const isSharedChatPage = typeof window !== "undefined" &&
window.location.pathname.startsWith('/shared-chat');
// Usar API key apenas para requisições específicas de agentes compartilhados ou na página de chat compartilhado
if ((isSharedAgentRequest || isSharedChatPage) && localStorage.getItem("shared_agent_api_key")) {
const apiKey = localStorage.getItem("shared_agent_api_key");
config.headers = config.headers || {};
config.headers["x-api-key"] = apiKey;
} else {
// Caso contrário, usar a autenticação normal com JWT
const match = document.cookie.match(/(?:^|; )access_token=([^;]*)/);
const token = match ? decodeURIComponent(match[1]) : null;
if (token) {
config.headers = config.headers || {};
config.headers["Authorization"] = `Bearer ${token}`;
}
}
}
return config;
});
// Interceptor to handle 401 Unauthorized responses
api.interceptors.response.use(
(response) => response,
(error) => {
// Check if we have a 401 Unauthorized error and we're in a browser context
if (error.response && error.response.status === 401 && typeof window !== "undefined") {
// Skip logout for login endpoint and other auth endpoints
const isAuthEndpoint = error.config.url && (
error.config.url.includes('/auth/login') ||
error.config.url.includes('/auth/register') ||
error.config.url.includes('/auth/forgot-password') ||
error.config.url.includes('/auth/reset-password')
);
// Skip logout for shared chat page
const isSharedChatPage = typeof window !== "undefined" &&
window.location.pathname.startsWith('/shared-chat');
if (!isAuthEndpoint && !isSharedChatPage) {
forceLogout();
}
}
return Promise.reject(error);
}
);
export default api;

View File

@@ -0,0 +1,56 @@
/*
┌──────────────────────────────────────────────────────────────────────────────┐
│ @author: Davidson Gomes │
│ @file: /services/authService.ts │
│ Developed by: Davidson Gomes │
│ Creation date: May 13, 2025 │
│ Contact: contato@evolution-api.com │
├──────────────────────────────────────────────────────────────────────────────┤
│ @copyright © Evolution API 2025. All rights reserved. │
│ Licensed under the Apache License, Version 2.0 │
│ │
│ You may not use this file except in compliance with the License. │
│ You may obtain a copy of the License at │
│ │
│ http://www.apache.org/licenses/LICENSE-2.0 │
│ │
│ Unless required by applicable law or agreed to in writing, software │
│ distributed under the License is distributed on an "AS IS" BASIS, │
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
│ See the License for the specific language governing permissions and │
│ limitations under the License. │
├──────────────────────────────────────────────────────────────────────────────┤
│ @important │
│ For any future changes to the code in this file, it is recommended to │
│ include, together with the modification, the information of the developer │
│ who changed it and the date of modification. │
└──────────────────────────────────────────────────────────────────────────────┘
*/
import api from "./api";
import {
RegisterRequest,
RegisterResponse,
LoginRequest,
LoginResponse,
ResendVerificationRequest,
ForgotPasswordRequest,
ResetPasswordRequest,
MeResponse,
ChangePasswordRequest,
} from "../types/auth";
export const register = (data: RegisterRequest) =>
api.post<RegisterResponse>("/api/v1/auth/register", data);
export const login = (data: LoginRequest) =>
api.post<LoginResponse>("/api/v1/auth/login", data);
export const verifyEmail = (code: string) =>
api.get(`/api/v1/auth/verify-email/${code}`);
export const resendVerification = (data: ResendVerificationRequest) =>
api.post("/api/v1/auth/resend-verification", data);
export const forgotPassword = (data: ForgotPasswordRequest) =>
api.post("/api/v1/auth/forgot-password", data);
export const resetPassword = (data: ResetPasswordRequest) =>
api.post("/api/v1/auth/reset-password", data);
export const getMe = () => api.post<MeResponse>("/api/v1/auth/me");
export const changePassword = (data: ChangePasswordRequest) =>
api.post("/api/v1/auth/change-password", data);

View File

@@ -0,0 +1,87 @@
/*
┌──────────────────────────────────────────────────────────────────────────────┐
│ @author: Davidson Gomes │
│ @file: /services/clientService.ts │
│ Developed by: Davidson Gomes │
│ Creation date: May 13, 2025 │
│ Contact: contato@evolution-api.com │
├──────────────────────────────────────────────────────────────────────────────┤
│ @copyright © Evolution API 2025. All rights reserved. │
│ Licensed under the Apache License, Version 2.0 │
│ │
│ You may not use this file except in compliance with the License. │
│ You may obtain a copy of the License at │
│ │
│ http://www.apache.org/licenses/LICENSE-2.0 │
│ │
│ Unless required by applicable law or agreed to in writing, software │
│ distributed under the License is distributed on an "AS IS" BASIS, │
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
│ See the License for the specific language governing permissions and │
│ limitations under the License. │
├──────────────────────────────────────────────────────────────────────────────┤
│ @important │
│ For any future changes to the code in this file, it is recommended to │
│ include, together with the modification, the information of the developer │
│ who changed it and the date of modification. │
└──────────────────────────────────────────────────────────────────────────────┘
*/
import api from "./api";
export interface Client {
id: string;
name: string;
email: string;
created_at: string;
users_count?: number;
agents_count?: number;
}
export interface CreateClientRequest {
name: string;
email: string;
password: string;
}
export interface UpdateClientRequest {
name: string;
email: string;
}
export interface ListClientsResponse {
items: Client[];
total: number;
}
export const createClient = async (client: any) => {
try {
const response = await api.post("/api/v1/clients", client);
return response.data;
} catch (error) {
throw error;
}
};
export const listClients = (skip = 0, limit = 10) =>
api.get<Client[]>(`/api/v1/clients/?skip=${skip}&limit=${limit}`);
export const getClient = (clientId: string) =>
api.get<Client>(`/api/v1/clients/${clientId}`);
export const updateClient = (clientId: string, data: UpdateClientRequest) =>
api.put<Client>(`/api/v1/clients/${clientId}`, data);
export const deleteClient = async (id: string) => {
try {
const response = await api.delete(`/api/v1/clients/${id}`);
return response.data;
} catch (error) {
throw error;
}
};
export const impersonateClient = async (id: string) => {
try {
const response = await api.post(`/api/v1/clients/${id}/impersonate`);
return response.data;
} catch (error) {
throw error;
}
};

View File

@@ -0,0 +1,45 @@
/*
┌──────────────────────────────────────────────────────────────────────────────┐
│ @author: Davidson Gomes │
│ @file: /services/mcpServerService.ts │
│ Developed by: Davidson Gomes │
│ Creation date: May 13, 2025 │
│ Contact: contato@evolution-api.com │
├──────────────────────────────────────────────────────────────────────────────┤
│ @copyright © Evolution API 2025. All rights reserved. │
│ Licensed under the Apache License, Version 2.0 │
│ │
│ You may not use this file except in compliance with the License. │
│ You may obtain a copy of the License at │
│ │
│ http://www.apache.org/licenses/LICENSE-2.0 │
│ │
│ Unless required by applicable law or agreed to in writing, software │
│ distributed under the License is distributed on an "AS IS" BASIS, │
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
│ See the License for the specific language governing permissions and │
│ limitations under the License. │
├──────────────────────────────────────────────────────────────────────────────┤
│ @important │
│ For any future changes to the code in this file, it is recommended to │
│ include, together with the modification, the information of the developer │
│ who changed it and the date of modification. │
└──────────────────────────────────────────────────────────────────────────────┘
*/
import api from "./api";
import { MCPServer, MCPServerCreate } from "../types/mcpServer";
export const createMCPServer = (data: MCPServerCreate) =>
api.post<MCPServer>("/api/v1/mcp-servers/", data);
export const listMCPServers = (skip = 0, limit = 100) =>
api.get<MCPServer[]>(`/api/v1/mcp-servers/?skip=${skip}&limit=${limit}`);
export const getMCPServer = (id: string) =>
api.get<MCPServer>(`/api/v1/mcp-servers/${id}`);
export const updateMCPServer = (id: string, data: MCPServerCreate) =>
api.put<MCPServer>(`/api/v1/mcp-servers/${id}`, data);
export const deleteMCPServer = (id: string) =>
api.delete(`/api/v1/mcp-servers/${id}`);

View File

@@ -0,0 +1,142 @@
/*
┌──────────────────────────────────────────────────────────────────────────────┐
│ @author: Davidson Gomes │
│ @file: /services/sessionService.ts │
│ Developed by: Davidson Gomes │
│ Creation date: May 13, 2025 │
│ Contact: contato@evolution-api.com │
├──────────────────────────────────────────────────────────────────────────────┤
│ @copyright © Evolution API 2025. All rights reserved. │
│ Licensed under the Apache License, Version 2.0 │
│ │
│ You may not use this file except in compliance with the License. │
│ You may obtain a copy of the License at │
│ │
│ http://www.apache.org/licenses/LICENSE-2.0 │
│ │
│ Unless required by applicable law or agreed to in writing, software │
│ distributed under the License is distributed on an "AS IS" BASIS, │
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
│ See the License for the specific language governing permissions and │
│ limitations under the License. │
├──────────────────────────────────────────────────────────────────────────────┤
│ @important │
│ For any future changes to the code in this file, it is recommended to │
│ include, together with the modification, the information of the developer │
│ who changed it and the date of modification. │
└──────────────────────────────────────────────────────────────────────────────┘
*/
import api from "./api";
export interface ChatSession {
id: string;
app_name: string;
user_id: string;
state: Record<string, any>;
events: any[];
last_update_time: number;
update_time: string;
create_time: string;
created_at: string;
agent_id: string;
client_id: string;
}
export interface ChatPart {
text?: string;
functionCall?: any;
function_call?: any;
functionResponse?: any;
function_response?: any;
inline_data?: {
data: string;
mime_type: string;
metadata?: {
filename?: string;
[key: string]: any;
};
fileId?: string;
};
videoMetadata?: any;
thought?: any;
codeExecutionResult?: any;
executableCode?: any;
file_data?: {
filename?: string;
fileId?: string;
[key: string]: any;
};
}
export interface AttachedFile {
filename: string;
content_type: string;
data?: string;
size?: number;
}
export interface InlineData {
type: string;
data: string;
}
export interface ChatMessage {
id: string;
content: {
parts: ChatPart[];
role: string;
inlineData?: InlineData[];
files?: AttachedFile[];
};
author: string;
timestamp: number;
[key: string]: any;
}
export const generateExternalId = () => {
const now = new Date();
return `${now.getFullYear()}${String(now.getMonth() + 1).padStart(
2,
"0"
)}${String(now.getDate()).padStart(2, "0")}_${String(now.getHours()).padStart(
2,
"0"
)}${String(now.getMinutes()).padStart(2, "0")}${String(
now.getSeconds()
).padStart(2, "0")}`;
};
export const listSessions = (clientId: string) =>
api.get<ChatSession[]>(`/api/v1/sessions/client/${clientId}`);
export const getSessionMessages = (sessionId: string) =>
api.get<ChatMessage[]>(`/api/v1/sessions/${sessionId}/messages`);
export const createSession = (clientId: string, agentId: string) => {
const externalId = generateExternalId();
const sessionId = `${externalId}_${agentId}`;
return api.post<ChatSession>(`/api/v1/sessions/`, {
id: sessionId,
client_id: clientId,
agent_id: agentId,
});
};
export const deleteSession = (sessionId: string) => {
return api.delete<ChatSession>(`/api/v1/sessions/${sessionId}`);
};
export const sendMessage = (
sessionId: string,
agentId: string,
message: string
) => {
const externalId = sessionId.split("_")[0];
return api.post<ChatMessage>(`/api/v1/chat`, {
agent_id: agentId,
external_id: externalId,
message: message,
});
};