diff --git a/archon-ui-main/src/config/api.ts b/archon-ui-main/src/config/api.ts index b77bf3904c..5f2fa58ee0 100644 --- a/archon-ui-main/src/config/api.ts +++ b/archon-ui-main/src/config/api.ts @@ -7,15 +7,29 @@ // Get the API URL from environment or construct it export function getApiUrl(): string { - // Check if VITE_API_URL is provided (set by docker-compose) + // 1. Priority: VITE_API_URL from environment (e.g., Docker) if (import.meta.env.VITE_API_URL) { - return import.meta.env.VITE_API_URL; + return import.meta.env.VITE_API_URL } - // In both development (via Vite proxy) and production, we use a relative path. - // This ensures that requests are proxied correctly by the dev server or - // sent to the same origin in production. - return ''; + // 2. Production mode: Use relative path + if (import.meta.env.PROD) { + return '' + } + + // 3. Development mode: Construct URL from port + const port = import.meta.env.ARCHON_SERVER_PORT + if (!port) { + throw new Error( + 'ARCHON_SERVER_PORT environment variable is required. ' + + 'Please set it in your .env file. ' + + 'Default value: 8181', + ) + } + + const protocol = window.location.protocol + const hostname = window.location.hostname + return `${protocol}//${hostname}:${port}` } // Get the base path for API endpoints diff --git a/archon-ui-main/src/services/mcpClientService.ts b/archon-ui-main/src/services/mcpClientService.ts index 2010c9bfec..1c73d6683a 100644 --- a/archon-ui-main/src/services/mcpClientService.ts +++ b/archon-ui-main/src/services/mcpClientService.ts @@ -89,13 +89,11 @@ const MCPToolSchema = z.object({ export type MCPTool = z.infer; export type MCPParameter = z.infer; -import { getApiUrl } from '../config/api'; - /** * MCP Client Service - Universal MCP client that connects to any MCP servers * This service communicates with the standalone Python MCP client service */ -class MCPClientService { +export class MCPClientService { private baseUrl = getApiUrl(); // ======================================== diff --git a/archon-ui-main/test/config/api.test.ts b/archon-ui-main/test/config/api.test.ts index ac06c78ef3..db4ea470f2 100644 --- a/archon-ui-main/test/config/api.test.ts +++ b/archon-ui-main/test/config/api.test.ts @@ -47,10 +47,11 @@ describe('API Configuration', () => { delete (import.meta.env as any).VITE_API_URL; delete (import.meta.env as any).ARCHON_SERVER_PORT; - const { getApiUrl } = await import('../../src/config/api'); - - expect(() => getApiUrl()).toThrow('ARCHON_SERVER_PORT environment variable is required'); - expect(() => getApiUrl()).toThrow('Default value: 8181'); + // The import() promise should reject because a top-level statement calls getApiUrl() + // which will throw an error when ARCHON_SERVER_PORT is not set. + await expect(import('../../src/config/api')).rejects.toThrow( + /ARCHON_SERVER_PORT environment variable is required.*Default value: 8181/ + ); }); it('should use ARCHON_SERVER_PORT when set in development', async () => { diff --git a/archon-ui-main/test/errors.test.tsx b/archon-ui-main/test/errors.test.tsx index 092a099415..3d955331a7 100644 --- a/archon-ui-main/test/errors.test.tsx +++ b/archon-ui-main/test/errors.test.tsx @@ -37,7 +37,6 @@ describe('Error Handling Tests', () => { }) test('timeout error simulation', async () => { - vi.useFakeTimers() const MockTimeoutComponent = () => { const [status, setStatus] = React.useState('idle') @@ -62,14 +61,8 @@ describe('Error Handling Tests', () => { fireEvent.click(screen.getByText('Start Request')) expect(screen.getByText('Loading...')).toBeInTheDocument() - // Fast-forward time - await act(async () => { - await vi.advanceTimersByTimeAsync(150) - }) - - const alert = await screen.findByRole('alert') + const alert = await screen.findByRole('alert', {}, { timeout: 500 }) expect(alert).toHaveTextContent('Request timed out') - vi.useRealTimers() }) test('form validation errors', () => {