diff --git a/archon-ui-main/src/components/layouts/MainLayout.tsx b/archon-ui-main/src/components/layouts/MainLayout.tsx index acc9188a0e..ee8ddac7c6 100644 --- a/archon-ui-main/src/components/layouts/MainLayout.tsx +++ b/archon-ui-main/src/components/layouts/MainLayout.tsx @@ -45,7 +45,8 @@ export const MainLayout: React.FC = ({ const timeoutId = setTimeout(() => controller.abort(), 5000); // Check if backend is responding with a simple health check - const response = await fetch(`${credentialsService['baseUrl']}/api/health`, { + // Always use the proxy endpoint to ensure it works through Vite proxy + const response = await fetch('/api/health', { method: 'GET', signal: controller.signal }); diff --git a/archon-ui-main/src/components/settings/FeaturesSection.tsx b/archon-ui-main/src/components/settings/FeaturesSection.tsx index c827c8ac57..6b1e1052e9 100644 --- a/archon-ui-main/src/components/settings/FeaturesSection.tsx +++ b/archon-ui-main/src/components/settings/FeaturesSection.tsx @@ -39,7 +39,7 @@ export const FeaturesSection = () => { const [logfireResponse, projectsResponse, projectsHealthResponse, disconnectScreenRes] = await Promise.all([ credentialsService.getCredential('LOGFIRE_ENABLED').catch(() => ({ value: undefined })), credentialsService.getCredential('PROJECTS_ENABLED').catch(() => ({ value: undefined })), - fetch(`${credentialsService['baseUrl']}/api/projects/health`).catch(() => null), + fetch('/api/projects/health').catch(() => null), credentialsService.getCredential('DISCONNECT_SCREEN_ENABLED').catch(() => ({ value: 'true' })) ]); @@ -58,7 +58,7 @@ export const FeaturesSection = () => { response: projectsHealthResponse, ok: projectsHealthResponse?.ok, status: projectsHealthResponse?.status, - url: `${credentialsService['baseUrl']}/api/projects/health` + url: '/api/projects/health' }); if (projectsHealthResponse && projectsHealthResponse.ok) { diff --git a/archon-ui-main/src/config/api.ts b/archon-ui-main/src/config/api.ts index 032cc97101..6c5f97ee9a 100644 --- a/archon-ui-main/src/config/api.ts +++ b/archon-ui-main/src/config/api.ts @@ -17,17 +17,9 @@ export function getApiUrl(): string { return import.meta.env.VITE_API_URL; } - // For development, construct from window location - const protocol = window.location.protocol; - const host = window.location.hostname; - // Use configured port or default to 8181 - const port = import.meta.env.VITE_ARCHON_SERVER_PORT || '8181'; - - if (!import.meta.env.VITE_ARCHON_SERVER_PORT) { - console.info('[Archon] Using default ARCHON_SERVER_PORT: 8181'); - } - - return `${protocol}//${host}:${port}`; + // In development mode, always use relative URLs to go through Vite proxy + // This ensures the proxy configuration in vite.config.ts is used + return ''; } // Get the base path for API endpoints diff --git a/archon-ui-main/src/services/bugReportService.ts b/archon-ui-main/src/services/bugReportService.ts index 296c2028ea..9e1319e0b7 100644 --- a/archon-ui-main/src/services/bugReportService.ts +++ b/archon-ui-main/src/services/bugReportService.ts @@ -161,7 +161,7 @@ class BugReportService { context: bugReport.context }; - const response = await fetch(`${getApiUrl()}/api/bug-report/github`, { + const response = await fetch('/api/bug-report/github', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/archon-ui-main/src/services/credentialsService.ts b/archon-ui-main/src/services/credentialsService.ts index bb14b48935..7b018c1894 100644 --- a/archon-ui-main/src/services/credentialsService.ts +++ b/archon-ui-main/src/services/credentialsService.ts @@ -56,7 +56,8 @@ export interface CodeExtractionSettings { import { getApiUrl } from "../config/api"; class CredentialsService { - private baseUrl = getApiUrl(); + // Always use relative URLs to go through Vite proxy + private baseUrl = ''; private handleCredentialError(error: any, context: string): Error { const errorMessage = error instanceof Error ? error.message : String(error); @@ -78,7 +79,7 @@ class CredentialsService { } async getAllCredentials(): Promise { - const response = await fetch(`${this.baseUrl}/api/credentials`); + const response = await fetch('/api/credentials'); if (!response.ok) { throw new Error("Failed to fetch credentials"); } @@ -87,7 +88,7 @@ class CredentialsService { async getCredentialsByCategory(category: string): Promise { const response = await fetch( - `${this.baseUrl}/api/credentials/categories/${category}`, + `/api/credentials/categories/${category}`, ); if (!response.ok) { throw new Error(`Failed to fetch credentials for category: ${category}`); @@ -128,7 +129,7 @@ class CredentialsService { async getCredential( key: string, ): Promise<{ key: string; value?: string; is_encrypted?: boolean }> { - const response = await fetch(`${this.baseUrl}/api/credentials/${key}`); + const response = await fetch(`/api/credentials/${key}`); if (!response.ok) { if (response.status === 404) { // Return empty object if credential not found @@ -222,7 +223,7 @@ class CredentialsService { async updateCredential(credential: Credential): Promise { try { const response = await fetch( - `${this.baseUrl}/api/credentials/${credential.key}`, + `/api/credentials/${credential.key}`, { method: "PUT", headers: { @@ -248,7 +249,7 @@ class CredentialsService { async createCredential(credential: Credential): Promise { try { - const response = await fetch(`${this.baseUrl}/api/credentials`, { + const response = await fetch('/api/credentials', { method: "POST", headers: { "Content-Type": "application/json", @@ -272,7 +273,7 @@ class CredentialsService { async deleteCredential(key: string): Promise { try { - const response = await fetch(`${this.baseUrl}/api/credentials/${key}`, { + const response = await fetch(`/api/credentials/${key}`, { method: "DELETE", }); diff --git a/archon-ui-main/src/services/mcpClientService.ts b/archon-ui-main/src/services/mcpClientService.ts index 2010c9bfec..af5bea9bed 100644 --- a/archon-ui-main/src/services/mcpClientService.ts +++ b/archon-ui-main/src/services/mcpClientService.ts @@ -96,7 +96,8 @@ import { getApiUrl } from '../config/api'; * This service communicates with the standalone Python MCP client service */ class MCPClientService { - private baseUrl = getApiUrl(); + // Always use relative URLs to go through Vite proxy + private baseUrl = ''; // ======================================== // CLIENT MANAGEMENT @@ -106,7 +107,7 @@ class MCPClientService { * Get all configured MCP clients */ async getClients(): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/`); + const response = await fetch('/api/mcp/clients/'); if (!response.ok) { throw new Error('Failed to get MCP clients'); @@ -119,7 +120,7 @@ class MCPClientService { * Create a new MCP client */ async createClient(config: MCPClientConfig): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/`, { + const response = await fetch('/api/mcp/clients/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(config) @@ -137,7 +138,7 @@ class MCPClientService { * Get a specific MCP client */ async getClient(clientId: string): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}`); + const response = await fetch(`/api/mcp/clients/${clientId}`); if (!response.ok) { const error = await response.json(); @@ -151,7 +152,7 @@ class MCPClientService { * Update an MCP client */ async updateClient(clientId: string, updates: Partial): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}`, { + const response = await fetch(`/api/mcp/clients/${clientId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(updates) @@ -169,7 +170,7 @@ class MCPClientService { * Delete an MCP client */ async deleteClient(clientId: string): Promise<{ success: boolean; message: string }> { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}`, { + const response = await fetch(`/api/mcp/clients/${clientId}`, { method: 'DELETE' }); @@ -189,7 +190,7 @@ class MCPClientService { * Connect to an MCP client */ async connectClient(clientId: string): Promise<{ success: boolean; message: string }> { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/connect`, { + const response = await fetch(`/api/mcp/clients/${clientId}/connect`, { method: 'POST' }); @@ -205,7 +206,7 @@ class MCPClientService { * Disconnect from an MCP client */ async disconnectClient(clientId: string): Promise<{ success: boolean; message: string }> { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/disconnect`, { + const response = await fetch(`/api/mcp/clients/${clientId}/disconnect`, { method: 'POST' }); @@ -221,7 +222,7 @@ class MCPClientService { * Get client status and health */ async getClientStatus(clientId: string): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/status`); + const response = await fetch(`/api/mcp/clients/${clientId}/status`); if (!response.ok) { const error = await response.json(); @@ -235,7 +236,7 @@ class MCPClientService { * Test a client configuration before saving */ async testClientConfig(config: MCPClientConfig): Promise<{ success: boolean; message: string }> { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/test-config`, { + const response = await fetch('/api/mcp/clients/test-config', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(config) @@ -257,7 +258,7 @@ class MCPClientService { * Get tools from a specific client */ async getClientTools(clientId: string): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/tools`); + const response = await fetch(`/api/mcp/clients/${clientId}/tools`); if (!response.ok) { const error = await response.json(); @@ -271,7 +272,7 @@ class MCPClientService { * Call a tool on a specific client */ async callClientTool(request: ToolCallRequest): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/tools/call`, { + const response = await fetch('/api/mcp/clients/tools/call', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request) @@ -289,7 +290,7 @@ class MCPClientService { * Get tools from all connected clients (including Archon via MCP client) */ async getAllAvailableTools(): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/tools/all`); + const response = await fetch('/api/mcp/clients/tools/all'); if (!response.ok) { const error = await response.json(); @@ -303,7 +304,7 @@ class MCPClientService { * Discover tools from a specific client (force refresh) */ async discoverClientTools(clientId: string): Promise { - const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/tools/discover`, { + const response = await fetch(`/api/mcp/clients/${clientId}/tools/discover`, { method: 'POST' }); diff --git a/archon-ui-main/src/services/testService.ts b/archon-ui-main/src/services/testService.ts index cf4b15d1c4..9b0ea40d82 100644 --- a/archon-ui-main/src/services/testService.ts +++ b/archon-ui-main/src/services/testService.ts @@ -42,7 +42,8 @@ export interface TestStatus { import { getApiUrl, getWebSocketUrl } from '../config/api'; // Use unified API configuration -const API_BASE_URL = getApiUrl(); +// Always use relative URLs to go through Vite proxy +const API_BASE_URL = ''; // Error class for test service errors export class TestServiceError extends Error { diff --git a/python/src/server/api_routes/knowledge_api.py b/python/src/server/api_routes/knowledge_api.py index 11e1f13f9e..44e6a05335 100644 --- a/python/src/server/api_routes/knowledge_api.py +++ b/python/src/server/api_routes/knowledge_api.py @@ -883,6 +883,9 @@ async def knowledge_health(): "status": "healthy", "service": "knowledge-api", "timestamp": datetime.now().isoformat(), + "ready": True, + "credentials_loaded": True, + "schema_valid": True, } return result