diff --git a/frontend/__tests__/api/file-service/file-service.api.test.ts b/frontend/__tests__/api/file-service/file-service.api.test.ts index 05b517be18..dce183a21d 100644 --- a/frontend/__tests__/api/file-service/file-service.api.test.ts +++ b/frontend/__tests__/api/file-service/file-service.api.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { FILE_VARIANTS_1, FILE_VARIANTS_2, @@ -10,20 +10,20 @@ import { * You can find the mock handlers in `frontend/src/mocks/file-service-handlers.ts`. */ -describe("OpenHands File API", () => { +describe("ConversationService File API", () => { it("should get a list of files", async () => { - await expect(OpenHands.getFiles("test-conversation-id")).resolves.toEqual( - FILE_VARIANTS_1, - ); + await expect( + ConversationService.getFiles("test-conversation-id"), + ).resolves.toEqual(FILE_VARIANTS_1); await expect( - OpenHands.getFiles("test-conversation-id-2"), + ConversationService.getFiles("test-conversation-id-2"), ).resolves.toEqual(FILE_VARIANTS_2); }); it("should get content of a file", async () => { await expect( - OpenHands.getFile("test-conversation-id", "file1.txt"), + ConversationService.getFile("test-conversation-id", "file1.txt"), ).resolves.toEqual("Content of file1.txt"); }); }); diff --git a/frontend/__tests__/components/features/chat/messages.test.tsx b/frontend/__tests__/components/features/chat/messages.test.tsx index 0d3c7dce20..577f6db5a1 100644 --- a/frontend/__tests__/components/features/chat/messages.test.tsx +++ b/frontend/__tests__/components/features/chat/messages.test.tsx @@ -8,7 +8,7 @@ import { UserMessageAction, } from "#/types/core/actions"; import { OpenHandsObservation } from "#/types/core/observations"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { Conversation } from "#/api/open-hands.types"; vi.mock("react-router", () => ({ @@ -80,7 +80,7 @@ describe("Messages", () => { }); it("should render a launch to microagent action button on chat messages only if it is a user message", () => { - const getConversationSpy = vi.spyOn(OpenHands, "getConversation"); + const getConversationSpy = vi.spyOn(ConversationService, "getConversation"); const mockConversation: Conversation = { conversation_id: "123", title: "Test Conversation", diff --git a/frontend/__tests__/components/features/conversation-panel/conversation-panel.test.tsx b/frontend/__tests__/components/features/conversation-panel/conversation-panel.test.tsx index 2b537f1e73..9ea5c0fefa 100644 --- a/frontend/__tests__/components/features/conversation-panel/conversation-panel.test.tsx +++ b/frontend/__tests__/components/features/conversation-panel/conversation-panel.test.tsx @@ -6,7 +6,7 @@ import { createRoutesStub } from "react-router"; import React from "react"; import { renderWithProviders } from "test-utils"; import { ConversationPanel } from "#/components/features/conversation-panel/conversation-panel"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { Conversation } from "#/api/open-hands.types"; describe("ConversationPanel", () => { @@ -85,7 +85,7 @@ describe("ConversationPanel", () => { vi.clearAllMocks(); vi.restoreAllMocks(); // Setup default mock for getUserConversations - vi.spyOn(OpenHands, "getUserConversations").mockResolvedValue({ + vi.spyOn(ConversationService, "getUserConversations").mockResolvedValue({ results: [...mockConversations], next_page_id: null, }); @@ -101,7 +101,10 @@ describe("ConversationPanel", () => { }); it("should display an empty state when there are no conversations", async () => { - const getUserConversationsSpy = vi.spyOn(OpenHands, "getUserConversations"); + const getUserConversationsSpy = vi.spyOn( + ConversationService, + "getUserConversations", + ); getUserConversationsSpy.mockResolvedValue({ results: [], next_page_id: null, @@ -114,7 +117,10 @@ describe("ConversationPanel", () => { }); it("should handle an error when fetching conversations", async () => { - const getUserConversationsSpy = vi.spyOn(OpenHands, "getUserConversations"); + const getUserConversationsSpy = vi.spyOn( + ConversationService, + "getUserConversations", + ); getUserConversationsSpy.mockRejectedValue( new Error("Failed to fetch conversations"), ); @@ -203,14 +209,17 @@ describe("ConversationPanel", () => { }, ]; - const getUserConversationsSpy = vi.spyOn(OpenHands, "getUserConversations"); + const getUserConversationsSpy = vi.spyOn( + ConversationService, + "getUserConversations", + ); getUserConversationsSpy.mockImplementation(async () => ({ results: mockData, next_page_id: null, })); const deleteUserConversationSpy = vi.spyOn( - OpenHands, + ConversationService, "deleteUserConversation", ); deleteUserConversationSpy.mockImplementation(async (id: string) => { @@ -260,7 +269,10 @@ describe("ConversationPanel", () => { it("should refetch data on rerenders", async () => { const user = userEvent.setup(); - const getUserConversationsSpy = vi.spyOn(OpenHands, "getUserConversations"); + const getUserConversationsSpy = vi.spyOn( + ConversationService, + "getUserConversations", + ); getUserConversationsSpy.mockResolvedValue({ results: [...mockConversations], next_page_id: null, @@ -357,7 +369,10 @@ describe("ConversationPanel", () => { }, ]; - const getUserConversationsSpy = vi.spyOn(OpenHands, "getUserConversations"); + const getUserConversationsSpy = vi.spyOn( + ConversationService, + "getUserConversations", + ); getUserConversationsSpy.mockResolvedValue({ results: mockRunningConversations, next_page_id: null, @@ -424,13 +439,19 @@ describe("ConversationPanel", () => { }, ]; - const getUserConversationsSpy = vi.spyOn(OpenHands, "getUserConversations"); + const getUserConversationsSpy = vi.spyOn( + ConversationService, + "getUserConversations", + ); getUserConversationsSpy.mockImplementation(async () => ({ results: mockData, next_page_id: null, })); - const stopConversationSpy = vi.spyOn(OpenHands, "stopConversation"); + const stopConversationSpy = vi.spyOn( + ConversationService, + "stopConversation", + ); stopConversationSpy.mockImplementation(async (id: string) => { const conversation = mockData.find((conv) => conv.conversation_id === id); if (conversation) { @@ -512,7 +533,10 @@ describe("ConversationPanel", () => { }, ]; - const getUserConversationsSpy = vi.spyOn(OpenHands, "getUserConversations"); + const getUserConversationsSpy = vi.spyOn( + ConversationService, + "getUserConversations", + ); getUserConversationsSpy.mockResolvedValue({ results: mockMixedStatusConversations, next_page_id: null, @@ -619,7 +643,10 @@ describe("ConversationPanel", () => { const user = userEvent.setup(); // Mock the updateConversation API call - const updateConversationSpy = vi.spyOn(OpenHands, "updateConversation"); + const updateConversationSpy = vi.spyOn( + ConversationService, + "updateConversation", + ); updateConversationSpy.mockResolvedValue(true); // Mock the toast function @@ -656,7 +683,10 @@ describe("ConversationPanel", () => { it("should save title when Enter key is pressed", async () => { const user = userEvent.setup(); - const updateConversationSpy = vi.spyOn(OpenHands, "updateConversation"); + const updateConversationSpy = vi.spyOn( + ConversationService, + "updateConversation", + ); updateConversationSpy.mockResolvedValue(true); renderConversationPanel(); @@ -685,7 +715,10 @@ describe("ConversationPanel", () => { it("should trim whitespace from title", async () => { const user = userEvent.setup(); - const updateConversationSpy = vi.spyOn(OpenHands, "updateConversation"); + const updateConversationSpy = vi.spyOn( + ConversationService, + "updateConversation", + ); updateConversationSpy.mockResolvedValue(true); renderConversationPanel(); @@ -714,7 +747,10 @@ describe("ConversationPanel", () => { it("should revert to original title when empty", async () => { const user = userEvent.setup(); - const updateConversationSpy = vi.spyOn(OpenHands, "updateConversation"); + const updateConversationSpy = vi.spyOn( + ConversationService, + "updateConversation", + ); updateConversationSpy.mockResolvedValue(true); renderConversationPanel(); @@ -740,7 +776,10 @@ describe("ConversationPanel", () => { it("should handle API error when updating title", async () => { const user = userEvent.setup(); - const updateConversationSpy = vi.spyOn(OpenHands, "updateConversation"); + const updateConversationSpy = vi.spyOn( + ConversationService, + "updateConversation", + ); updateConversationSpy.mockRejectedValue(new Error("API Error")); vi.mock("#/utils/custom-toast-handlers", () => ({ @@ -807,7 +846,10 @@ describe("ConversationPanel", () => { it("should not call API when title is unchanged", async () => { const user = userEvent.setup(); - const updateConversationSpy = vi.spyOn(OpenHands, "updateConversation"); + const updateConversationSpy = vi.spyOn( + ConversationService, + "updateConversation", + ); updateConversationSpy.mockResolvedValue(true); renderConversationPanel(); @@ -833,7 +875,10 @@ describe("ConversationPanel", () => { it("should handle special characters in title", async () => { const user = userEvent.setup(); - const updateConversationSpy = vi.spyOn(OpenHands, "updateConversation"); + const updateConversationSpy = vi.spyOn( + ConversationService, + "updateConversation", + ); updateConversationSpy.mockResolvedValue(true); renderConversationPanel(); diff --git a/frontend/__tests__/components/features/home/new-conversation.test.tsx b/frontend/__tests__/components/features/home/new-conversation.test.tsx index 96dd8387b2..eb0c7167c0 100644 --- a/frontend/__tests__/components/features/home/new-conversation.test.tsx +++ b/frontend/__tests__/components/features/home/new-conversation.test.tsx @@ -5,8 +5,8 @@ import { createRoutesStub } from "react-router"; import { setupStore } from "test-utils"; import { describe, expect, it, vi } from "vitest"; import userEvent from "@testing-library/user-event"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { NewConversation } from "#/components/features/home/new-conversation/new-conversation"; -import OpenHands from "#/api/open-hands"; // Mock the translation function vi.mock("react-i18next", async () => { @@ -54,7 +54,10 @@ const renderNewConversation = () => { describe("NewConversation", () => { it("should create an empty conversation and redirect when pressing the launch from scratch button", async () => { - const createConversationSpy = vi.spyOn(OpenHands, "createConversation"); + const createConversationSpy = vi.spyOn( + ConversationService, + "createConversation", + ); renderNewConversation(); diff --git a/frontend/__tests__/components/features/home/repo-connector.test.tsx b/frontend/__tests__/components/features/home/repo-connector.test.tsx index 97e2b7df7c..d04be1bb5a 100644 --- a/frontend/__tests__/components/features/home/repo-connector.test.tsx +++ b/frontend/__tests__/components/features/home/repo-connector.test.tsx @@ -6,7 +6,7 @@ import { setupStore } from "test-utils"; import { Provider } from "react-redux"; import { createRoutesStub, Outlet } from "react-router"; import SettingsService from "#/settings-service/settings-service.api"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import GitService from "#/api/git-service/git-service.api"; import OptionService from "#/api/option-service/option-service.api"; import { GitRepository } from "#/types/git"; @@ -315,7 +315,10 @@ describe("RepoConnector", () => { }); it("should create a conversation and redirect with the selected repo when pressing the launch button", async () => { - const createConversationSpy = vi.spyOn(OpenHands, "createConversation"); + const createConversationSpy = vi.spyOn( + ConversationService, + "createConversation", + ); createConversationSpy.mockResolvedValue({ conversation_id: "mock-conversation-id", title: "Test Conversation", @@ -400,7 +403,10 @@ describe("RepoConnector", () => { }); it("should change the launch button text to 'Loading...' when creating a conversation", async () => { - const createConversationSpy = vi.spyOn(OpenHands, "createConversation"); + const createConversationSpy = vi.spyOn( + ConversationService, + "createConversation", + ); createConversationSpy.mockImplementation(() => new Promise(() => {})); // Never resolves to keep loading state const retrieveUserGitRepositoriesSpy = vi.spyOn( GitService, diff --git a/frontend/__tests__/components/features/home/repo-selection-form.test.tsx b/frontend/__tests__/components/features/home/repo-selection-form.test.tsx index a34163ff6e..42a4087a4e 100644 --- a/frontend/__tests__/components/features/home/repo-selection-form.test.tsx +++ b/frontend/__tests__/components/features/home/repo-selection-form.test.tsx @@ -2,7 +2,6 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, vi, beforeEach, it } from "vitest"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { RepositorySelectionForm } from "../../../../src/components/features/home/repo-selection-form"; -import OpenHands from "#/api/open-hands"; import UserService from "#/api/user-service/user-service.api"; import GitService from "#/api/git-service/git-service.api"; import { GitRepository } from "#/types/git"; diff --git a/frontend/__tests__/components/features/home/task-card.test.tsx b/frontend/__tests__/components/features/home/task-card.test.tsx index b8be487729..742a31784f 100644 --- a/frontend/__tests__/components/features/home/task-card.test.tsx +++ b/frontend/__tests__/components/features/home/task-card.test.tsx @@ -5,7 +5,7 @@ import userEvent from "@testing-library/user-event"; import { Provider } from "react-redux"; import { createRoutesStub } from "react-router"; import { setupStore } from "test-utils"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import UserService from "#/api/user-service/user-service.api"; import GitService from "#/api/git-service/git-service.api"; import { TaskCard } from "#/components/features/home/tasks/task-card"; @@ -59,7 +59,10 @@ describe("TaskCard", () => { }); it("should call createConversation when clicking the launch button", async () => { - const createConversationSpy = vi.spyOn(OpenHands, "createConversation"); + const createConversationSpy = vi.spyOn( + ConversationService, + "createConversation", + ); renderTaskCard(); @@ -82,7 +85,10 @@ describe("TaskCard", () => { }); it("should call create conversation with suggest task trigger and selected suggested task", async () => { - const createConversationSpy = vi.spyOn(OpenHands, "createConversation"); + const createConversationSpy = vi.spyOn( + ConversationService, + "createConversation", + ); renderTaskCard(MOCK_TASK_1); @@ -108,7 +114,10 @@ describe("TaskCard", () => { }); it("should navigate to the conversation page after creating a conversation", async () => { - const createConversationSpy = vi.spyOn(OpenHands, "createConversation"); + const createConversationSpy = vi.spyOn( + ConversationService, + "createConversation", + ); createConversationSpy.mockResolvedValue({ conversation_id: "test-conversation-id", title: "Test Conversation", diff --git a/frontend/__tests__/components/features/microagent-management/microagent-management.test.tsx b/frontend/__tests__/components/features/microagent-management/microagent-management.test.tsx index f342485d37..719b809f74 100644 --- a/frontend/__tests__/components/features/microagent-management/microagent-management.test.tsx +++ b/frontend/__tests__/components/features/microagent-management/microagent-management.test.tsx @@ -7,7 +7,7 @@ import React from "react"; import { renderWithProviders } from "test-utils"; import MicroagentManagement from "#/routes/microagent-management"; import { MicroagentManagementMain } from "#/components/features/microagent-management/microagent-management-main"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import GitService from "#/api/git-service/git-service.api"; import { GitRepository } from "#/types/git"; import { RepositoryMicroagent } from "#/types/microagent-management"; @@ -241,7 +241,7 @@ describe("MicroagentManagement", () => { ...mockMicroagents, ]); // Setup default mock for searchConversations - vi.spyOn(OpenHands, "searchConversations").mockResolvedValue([ + vi.spyOn(ConversationService, "searchConversations").mockResolvedValue([ ...mockConversations, ]); // Setup default mock for getRepositoryMicroagentContent diff --git a/frontend/__tests__/components/modals/microagents/microagent-modal.test.tsx b/frontend/__tests__/components/modals/microagents/microagent-modal.test.tsx index 2206778d12..9cfb096eb0 100644 --- a/frontend/__tests__/components/modals/microagents/microagent-modal.test.tsx +++ b/frontend/__tests__/components/modals/microagents/microagent-modal.test.tsx @@ -3,7 +3,7 @@ import userEvent from "@testing-library/user-event"; import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { renderWithProviders } from "test-utils"; import { MicroagentsModal } from "#/components/features/conversation-panel/microagents-modal"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { AgentState } from "#/types/agent-state"; vi.mock("react-redux", async () => { @@ -48,7 +48,7 @@ describe("MicroagentsModal - Refresh Button", () => { vi.clearAllMocks(); // Setup default mock for getUserConversations - vi.spyOn(OpenHands, "getMicroagents").mockResolvedValue({ + vi.spyOn(ConversationService, "getMicroagents").mockResolvedValue({ microagents: mockMicroagents, }); }); @@ -73,7 +73,7 @@ describe("MicroagentsModal - Refresh Button", () => { renderWithProviders(); - const refreshSpy = vi.spyOn(OpenHands, "getMicroagents"); + const refreshSpy = vi.spyOn(ConversationService, "getMicroagents"); const refreshButton = screen.getByTestId("refresh-microagents"); await user.click(refreshButton); diff --git a/frontend/__tests__/routes/_oh.test.tsx b/frontend/__tests__/routes/_oh.test.tsx index 0a84390f0a..7737eaa7f7 100644 --- a/frontend/__tests__/routes/_oh.test.tsx +++ b/frontend/__tests__/routes/_oh.test.tsx @@ -11,7 +11,6 @@ import i18n from "#/i18n"; import OptionService from "#/api/option-service/option-service.api"; import * as CaptureConsent from "#/utils/handle-capture-consent"; import SettingsService from "#/settings-service/settings-service.api"; -import OpenHands from "#/api/open-hands"; import * as ToastHandlers from "#/utils/custom-toast-handlers"; describe("frontend/routes/_oh", () => { diff --git a/frontend/__tests__/routes/git-settings.test.tsx b/frontend/__tests__/routes/git-settings.test.tsx index 5e75c4f9fb..8b35abad3f 100644 --- a/frontend/__tests__/routes/git-settings.test.tsx +++ b/frontend/__tests__/routes/git-settings.test.tsx @@ -7,7 +7,6 @@ import i18next from "i18next"; import { I18nextProvider } from "react-i18next"; import GitSettingsScreen from "#/routes/git-settings"; import SettingsService from "#/settings-service/settings-service.api"; -import OpenHands from "#/api/open-hands"; import OptionService from "#/api/option-service/option-service.api"; import AuthService from "#/api/auth-service/auth-service.api"; import { MOCK_DEFAULT_USER_SETTINGS } from "#/mocks/handlers"; diff --git a/frontend/__tests__/routes/llm-settings.test.tsx b/frontend/__tests__/routes/llm-settings.test.tsx index 9ca03b8a13..0662fea5cb 100644 --- a/frontend/__tests__/routes/llm-settings.test.tsx +++ b/frontend/__tests__/routes/llm-settings.test.tsx @@ -4,7 +4,6 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import { QueryClientProvider, QueryClient } from "@tanstack/react-query"; import LlmSettingsScreen from "#/routes/llm-settings"; import SettingsService from "#/settings-service/settings-service.api"; -import OpenHands from "#/api/open-hands"; import OptionService from "#/api/option-service/option-service.api"; import { MOCK_DEFAULT_USER_SETTINGS, diff --git a/frontend/__tests__/routes/secrets-settings.test.tsx b/frontend/__tests__/routes/secrets-settings.test.tsx index 78e9c555ed..5517e965aa 100644 --- a/frontend/__tests__/routes/secrets-settings.test.tsx +++ b/frontend/__tests__/routes/secrets-settings.test.tsx @@ -7,7 +7,6 @@ import SecretsSettingsScreen from "#/routes/secrets-settings"; import { SecretsService } from "#/api/secrets-service"; import { GetSecretsResponse } from "#/api/secrets-service.types"; import SettingsService from "#/settings-service/settings-service.api"; -import OpenHands from "#/api/open-hands"; import OptionService from "#/api/option-service/option-service.api"; import { MOCK_DEFAULT_USER_SETTINGS } from "#/mocks/handlers"; diff --git a/frontend/__tests__/routes/settings-with-payment.test.tsx b/frontend/__tests__/routes/settings-with-payment.test.tsx index 08a6020aed..e373d3dc98 100644 --- a/frontend/__tests__/routes/settings-with-payment.test.tsx +++ b/frontend/__tests__/routes/settings-with-payment.test.tsx @@ -3,14 +3,15 @@ import userEvent from "@testing-library/user-event"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createRoutesStub } from "react-router"; import { renderWithProviders } from "test-utils"; -import OpenHands from "#/api/open-hands"; import SettingsScreen from "#/routes/settings"; import { PaymentForm } from "#/components/features/payment/payment-form"; import * as useSettingsModule from "#/hooks/query/use-settings"; // Mock the useSettings hook vi.mock("#/hooks/query/use-settings", async () => { - const actual = await vi.importActual("#/hooks/query/use-settings"); + const actual = await vi.importActual< + typeof import("#/hooks/query/use-settings") + >("#/hooks/query/use-settings"); return { ...actual, useSettings: vi.fn().mockReturnValue({ @@ -24,21 +25,22 @@ vi.mock("#/hooks/query/use-settings", async () => { // Mock the i18next hook vi.mock("react-i18next", async () => { - const actual = await vi.importActual("react-i18next"); + const actual = + await vi.importActual("react-i18next"); return { ...actual, useTranslation: () => ({ t: (key: string) => { const translations: Record = { - "SETTINGS$NAV_INTEGRATIONS": "Integrations", - "SETTINGS$NAV_APPLICATION": "Application", - "SETTINGS$NAV_CREDITS": "Credits", - "SETTINGS$NAV_API_KEYS": "API Keys", - "SETTINGS$NAV_LLM": "LLM", - "SETTINGS$NAV_USER": "User", - "SETTINGS$NAV_SECRETS": "Secrets", - "SETTINGS$NAV_MCP": "MCP", - "SETTINGS$TITLE": "Settings" + SETTINGS$NAV_INTEGRATIONS: "Integrations", + SETTINGS$NAV_APPLICATION: "Application", + SETTINGS$NAV_CREDITS: "Credits", + SETTINGS$NAV_API_KEYS: "API Keys", + SETTINGS$NAV_LLM: "LLM", + SETTINGS$NAV_USER: "User", + SETTINGS$NAV_SECRETS: "Secrets", + SETTINGS$NAV_MCP: "MCP", + SETTINGS$TITLE: "Settings", }; return translations[key] || key; }, diff --git a/frontend/__tests__/routes/settings.test.tsx b/frontend/__tests__/routes/settings.test.tsx index c6ae026eb7..f960f18ecb 100644 --- a/frontend/__tests__/routes/settings.test.tsx +++ b/frontend/__tests__/routes/settings.test.tsx @@ -3,7 +3,6 @@ import { createRoutesStub } from "react-router"; import { describe, expect, it, vi } from "vitest"; import { QueryClientProvider } from "@tanstack/react-query"; import SettingsScreen, { clientLoader } from "#/routes/settings"; -import OpenHands from "#/api/open-hands"; import OptionService from "#/api/option-service/option-service.api"; // Mock the i18next hook diff --git a/frontend/src/api/open-hands.ts b/frontend/src/api/conversation-service/conversation-service.api.ts similarity index 90% rename from frontend/src/api/open-hands.ts rename to frontend/src/api/conversation-service/conversation-service.api.ts index 8c850ca819..f426b56a48 100644 --- a/frontend/src/api/open-hands.ts +++ b/frontend/src/api/conversation-service/conversation-service.api.ts @@ -6,21 +6,19 @@ import { Conversation, ResultSet, GetTrajectoryResponse, - GitChangeDiff, - GitChange, GetMicroagentsResponse, GetMicroagentPromptResponse, CreateMicroagent, FileUploadSuccessResponse, GetFilesResponse, GetFileResponse, -} from "./open-hands.types"; -import { openHands } from "./open-hands-axios"; +} from "../open-hands.types"; +import { openHands } from "../open-hands-axios"; import { Provider } from "#/types/settings"; import { SuggestedTask } from "#/utils/types"; import { BatchFeedbackData } from "#/hooks/query/use-batch-feedback"; -class OpenHands { +class ConversationService { private static currentConversation: Conversation | null = null; /** @@ -322,30 +320,6 @@ class OpenHands { return data; } - static async getGitChanges(conversationId: string): Promise { - const url = `${this.getConversationUrl(conversationId)}/git/changes`; - const { data } = await openHands.get(url, { - headers: this.getConversationHeaders(), - }); - return data; - } - - static async getGitChangeDiff( - conversationId: string, - path: string, - ): Promise { - const url = `${this.getConversationUrl(conversationId)}/git/diff`; - const { data } = await openHands.get(url, { - params: { path }, - headers: this.getConversationHeaders(), - }); - return data; - } - - /** - * @returns A list of repositories - */ - /** * Get the available microagents associated with a conversation * @param conversationId The ID of the conversation @@ -361,21 +335,6 @@ class OpenHands { return data; } - /** - * Get the available microagents for a repository - * @param owner The repository owner - * @param repo The repository name - * @returns The available microagents for the repository - */ - - /** - * Get the content of a specific microagent from a repository - * @param owner The repository owner - * @param repo The repository name - * @param filePath The path to the microagent file within the repository - * @returns The microagent content and metadata - */ - static async getMicroagentPrompt( conversationId: string, eventId: number, @@ -465,4 +424,4 @@ class OpenHands { } } -export default OpenHands; +export default ConversationService; diff --git a/frontend/src/api/conversation.utils.ts b/frontend/src/api/conversation.utils.ts index cd1db7d34d..a0a9acd4ad 100644 --- a/frontend/src/api/conversation.utils.ts +++ b/frontend/src/api/conversation.utils.ts @@ -1,4 +1,4 @@ -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; /** * Returns a URL compatible for the file service @@ -6,4 +6,4 @@ import OpenHands from "#/api/open-hands"; * @returns URL of the conversation */ export const getConversationUrl = (conversationId: string) => - OpenHands.getConversationUrl(conversationId); + ConversationService.getConversationUrl(conversationId); diff --git a/frontend/src/api/git-service/git-service.api.ts b/frontend/src/api/git-service/git-service.api.ts index e175dd8fbe..4929ed5f90 100644 --- a/frontend/src/api/git-service/git-service.api.ts +++ b/frontend/src/api/git-service/git-service.api.ts @@ -3,7 +3,12 @@ import { Provider } from "#/types/settings"; import { GitRepository, PaginatedBranchesResponse, Branch } from "#/types/git"; import { extractNextPageFromLink } from "#/utils/extract-next-page-from-link"; import { RepositoryMicroagent } from "#/types/microagent-management"; -import { MicroagentContentResponse } from "../open-hands.types"; +import { + MicroagentContentResponse, + GitChange, + GitChangeDiff, +} from "../open-hands.types"; +import ConversationService from "../conversation-service/conversation-service.api"; /** * Git Service API - Handles all Git-related API endpoints @@ -210,6 +215,37 @@ class GitService { ); return data; } + + /** + * Get git changes for a conversation + * @param conversationId The conversation ID + * @returns List of git changes + */ + static async getGitChanges(conversationId: string): Promise { + const url = `${ConversationService.getConversationUrl(conversationId)}/git/changes`; + const { data } = await openHands.get(url, { + headers: ConversationService.getConversationHeaders(), + }); + return data; + } + + /** + * Get git change diff for a specific file + * @param conversationId The conversation ID + * @param path The file path + * @returns Git change diff + */ + static async getGitChangeDiff( + conversationId: string, + path: string, + ): Promise { + const url = `${ConversationService.getConversationUrl(conversationId)}/git/diff`; + const { data } = await openHands.get(url, { + params: { path }, + headers: ConversationService.getConversationHeaders(), + }); + return data; + } } export default GitService; diff --git a/frontend/src/components/features/conversation-panel/conversation-card/conversation-card.tsx b/frontend/src/components/features/conversation-panel/conversation-card/conversation-card.tsx index ad82644cb7..f2df9a8bf2 100644 --- a/frontend/src/components/features/conversation-panel/conversation-card/conversation-card.tsx +++ b/frontend/src/components/features/conversation-panel/conversation-card/conversation-card.tsx @@ -13,7 +13,7 @@ import { BaseModal } from "../../../shared/modals/base-modal/base-modal"; import { RootState } from "#/store"; import { I18nKey } from "#/i18n/declaration"; import { transformVSCodeUrl } from "#/utils/vscode-url-helper"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useWsClient } from "#/context/ws-client-provider"; import { isSystemMessage } from "#/types/core/guards"; import { ConversationStatus } from "#/types/conversation-status"; @@ -108,7 +108,7 @@ export function ConversationCard({ // Fetch the VS Code URL from the API if (conversationId) { try { - const data = await OpenHands.getVSCodeUrl(conversationId); + const data = await ConversationService.getVSCodeUrl(conversationId); if (data.vscode_url) { const transformedUrl = transformVSCodeUrl(data.vscode_url); if (transformedUrl) { diff --git a/frontend/src/components/features/conversation/conversation-tabs/vscode-tooltip-content.tsx b/frontend/src/components/features/conversation/conversation-tabs/vscode-tooltip-content.tsx index dbf36d9bf5..b65c901f97 100644 --- a/frontend/src/components/features/conversation/conversation-tabs/vscode-tooltip-content.tsx +++ b/frontend/src/components/features/conversation/conversation-tabs/vscode-tooltip-content.tsx @@ -5,7 +5,7 @@ import { I18nKey } from "#/i18n/declaration"; import { RUNTIME_INACTIVE_STATES } from "#/types/agent-state"; import { transformVSCodeUrl } from "#/utils/vscode-url-helper"; import { useConversationId } from "#/hooks/use-conversation-id"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { RootState } from "#/store"; export function VSCodeTooltipContent() { @@ -20,7 +20,7 @@ export function VSCodeTooltipContent() { if (conversationId) { try { - const data = await OpenHands.getVSCodeUrl(conversationId); + const data = await ConversationService.getVSCodeUrl(conversationId); if (data.vscode_url) { const transformedUrl = transformVSCodeUrl(data.vscode_url); if (transformedUrl) { diff --git a/frontend/src/hooks/mutation/use-create-conversation.ts b/frontend/src/hooks/mutation/use-create-conversation.ts index b312cc6295..6c97d8fba0 100644 --- a/frontend/src/hooks/mutation/use-create-conversation.ts +++ b/frontend/src/hooks/mutation/use-create-conversation.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; import posthog from "posthog-js"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { SuggestedTask } from "#/utils/types"; import { Provider } from "#/types/settings"; import { CreateMicroagent } from "#/api/open-hands.types"; @@ -31,7 +31,7 @@ export const useCreateConversation = () => { createMicroagent, } = variables; - return OpenHands.createConversation( + return ConversationService.createConversation( repository?.name, repository?.gitProvider, query, diff --git a/frontend/src/hooks/mutation/use-delete-conversation.ts b/frontend/src/hooks/mutation/use-delete-conversation.ts index cedc5475ca..e654cd6d7e 100644 --- a/frontend/src/hooks/mutation/use-delete-conversation.ts +++ b/frontend/src/hooks/mutation/use-delete-conversation.ts @@ -1,12 +1,12 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; export const useDeleteConversation = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: (variables: { conversationId: string }) => - OpenHands.deleteUserConversation(variables.conversationId), + ConversationService.deleteUserConversation(variables.conversationId), onMutate: async (variables) => { await queryClient.cancelQueries({ queryKey: ["user", "conversations"] }); const previousConversations = queryClient.getQueryData([ diff --git a/frontend/src/hooks/mutation/use-get-trajectory.ts b/frontend/src/hooks/mutation/use-get-trajectory.ts index e2ad96e64d..9969a710b9 100644 --- a/frontend/src/hooks/mutation/use-get-trajectory.ts +++ b/frontend/src/hooks/mutation/use-get-trajectory.ts @@ -1,7 +1,7 @@ import { useMutation } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; export const useGetTrajectory = () => useMutation({ - mutationFn: (cid: string) => OpenHands.getTrajectory(cid), + mutationFn: (cid: string) => ConversationService.getTrajectory(cid), }); diff --git a/frontend/src/hooks/mutation/use-start-conversation.ts b/frontend/src/hooks/mutation/use-start-conversation.ts index be2046b7b1..4d3e3a9f80 100644 --- a/frontend/src/hooks/mutation/use-start-conversation.ts +++ b/frontend/src/hooks/mutation/use-start-conversation.ts @@ -1,5 +1,5 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { Provider } from "#/types/settings"; export const useStartConversation = () => { @@ -10,7 +10,7 @@ export const useStartConversation = () => { conversationId: string; providers?: Provider[]; }) => - OpenHands.startConversation( + ConversationService.startConversation( variables.conversationId, variables.providers, ), diff --git a/frontend/src/hooks/mutation/use-stop-conversation.ts b/frontend/src/hooks/mutation/use-stop-conversation.ts index 230a4499c5..abb1ae801e 100644 --- a/frontend/src/hooks/mutation/use-stop-conversation.ts +++ b/frontend/src/hooks/mutation/use-stop-conversation.ts @@ -1,12 +1,12 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; export const useStopConversation = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: (variables: { conversationId: string }) => - OpenHands.stopConversation(variables.conversationId), + ConversationService.stopConversation(variables.conversationId), onMutate: async () => { await queryClient.cancelQueries({ queryKey: ["user", "conversations"] }); const previousConversations = queryClient.getQueryData([ diff --git a/frontend/src/hooks/mutation/use-submit-conversation-feedback.ts b/frontend/src/hooks/mutation/use-submit-conversation-feedback.ts index e01a4a155e..24753bb2e5 100644 --- a/frontend/src/hooks/mutation/use-submit-conversation-feedback.ts +++ b/frontend/src/hooks/mutation/use-submit-conversation-feedback.ts @@ -1,5 +1,5 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useConversationId } from "#/hooks/use-conversation-id"; import { BatchFeedbackData, @@ -18,7 +18,7 @@ export const useSubmitConversationFeedback = () => { return useMutation({ mutationFn: ({ rating, eventId, reason }: SubmitConversationFeedbackArgs) => - OpenHands.submitConversationFeedback( + ConversationService.submitConversationFeedback( conversationId, rating, eventId, diff --git a/frontend/src/hooks/mutation/use-submit-feedback.ts b/frontend/src/hooks/mutation/use-submit-feedback.ts index 430b0d3f05..c04e4b964c 100644 --- a/frontend/src/hooks/mutation/use-submit-feedback.ts +++ b/frontend/src/hooks/mutation/use-submit-feedback.ts @@ -1,6 +1,6 @@ import { useMutation } from "@tanstack/react-query"; import { Feedback } from "#/api/open-hands.types"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useConversationId } from "#/hooks/use-conversation-id"; import { displayErrorToast } from "#/utils/custom-toast-handlers"; @@ -12,7 +12,7 @@ export const useSubmitFeedback = () => { const { conversationId } = useConversationId(); return useMutation({ mutationFn: ({ feedback }: SubmitFeedbackArgs) => - OpenHands.submitFeedback(conversationId, feedback), + ConversationService.submitFeedback(conversationId, feedback), onError: (error) => { displayErrorToast(error.message); }, diff --git a/frontend/src/hooks/mutation/use-update-conversation.ts b/frontend/src/hooks/mutation/use-update-conversation.ts index fb82ccd7da..051ab0ec28 100644 --- a/frontend/src/hooks/mutation/use-update-conversation.ts +++ b/frontend/src/hooks/mutation/use-update-conversation.ts @@ -1,12 +1,12 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; export const useUpdateConversation = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: (variables: { conversationId: string; newTitle: string }) => - OpenHands.updateConversation(variables.conversationId, { + ConversationService.updateConversation(variables.conversationId, { title: variables.newTitle, }), onMutate: async (variables) => { diff --git a/frontend/src/hooks/mutation/use-upload-files.ts b/frontend/src/hooks/mutation/use-upload-files.ts index b59f3b3739..2132ba4a33 100644 --- a/frontend/src/hooks/mutation/use-upload-files.ts +++ b/frontend/src/hooks/mutation/use-upload-files.ts @@ -1,11 +1,14 @@ import { useMutation } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; export const useUploadFiles = () => useMutation({ mutationKey: ["upload-files"], mutationFn: (variables: { conversationId: string; files: File[] }) => - OpenHands.uploadFiles(variables.conversationId!, variables.files), + ConversationService.uploadFiles( + variables.conversationId!, + variables.files, + ), onSuccess: async () => {}, meta: { disableToast: true, diff --git a/frontend/src/hooks/query/use-active-conversation.ts b/frontend/src/hooks/query/use-active-conversation.ts index 11e1b5ed8e..452dba9261 100644 --- a/frontend/src/hooks/query/use-active-conversation.ts +++ b/frontend/src/hooks/query/use-active-conversation.ts @@ -1,7 +1,7 @@ import { useEffect } from "react"; import { useConversationId } from "#/hooks/use-conversation-id"; import { useUserConversation } from "./use-user-conversation"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; export const useActiveConversation = () => { const { conversationId } = useConversationId(); @@ -16,7 +16,7 @@ export const useActiveConversation = () => { useEffect(() => { const conversation = userConversation.data; - OpenHands.setCurrentConversation(conversation || null); + ConversationService.setCurrentConversation(conversation || null); }, [ conversationId, userConversation.isFetched, diff --git a/frontend/src/hooks/query/use-active-host.ts b/frontend/src/hooks/query/use-active-host.ts index 4c51498c35..ec20201689 100644 --- a/frontend/src/hooks/query/use-active-host.ts +++ b/frontend/src/hooks/query/use-active-host.ts @@ -1,7 +1,7 @@ import { useQueries, useQuery } from "@tanstack/react-query"; import axios from "axios"; import React from "react"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useConversationId } from "#/hooks/use-conversation-id"; import { useRuntimeIsReady } from "#/hooks/use-runtime-is-ready"; @@ -13,7 +13,7 @@ export const useActiveHost = () => { const { data } = useQuery({ queryKey: [conversationId, "hosts"], queryFn: async () => { - const hosts = await OpenHands.getWebHosts(conversationId); + const hosts = await ConversationService.getWebHosts(conversationId); return { hosts }; }, enabled: runtimeIsReady && !!conversationId, diff --git a/frontend/src/hooks/query/use-batch-feedback.ts b/frontend/src/hooks/query/use-batch-feedback.ts index 01bf72953b..e49e2761c1 100644 --- a/frontend/src/hooks/query/use-batch-feedback.ts +++ b/frontend/src/hooks/query/use-batch-feedback.ts @@ -1,6 +1,6 @@ import React from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useConversationId } from "#/hooks/use-conversation-id"; import { useConfig } from "#/hooks/query/use-config"; import { useRuntimeIsReady } from "#/hooks/use-runtime-is-ready"; @@ -30,7 +30,7 @@ export const useBatchFeedback = () => { const query = useQuery({ queryKey: getFeedbackQueryKey(conversationId), - queryFn: () => OpenHands.getBatchFeedback(conversationId!), + queryFn: () => ConversationService.getBatchFeedback(conversationId!), enabled: runtimeIsReady && !!conversationId && config?.APP_MODE === "saas", staleTime: 1000 * 60 * 5, // 5 minutes gcTime: 1000 * 60 * 15, // 15 minutes diff --git a/frontend/src/hooks/query/use-conversation-config.ts b/frontend/src/hooks/query/use-conversation-config.ts index 3a6443c094..7f851f78e2 100644 --- a/frontend/src/hooks/query/use-conversation-config.ts +++ b/frontend/src/hooks/query/use-conversation-config.ts @@ -1,7 +1,7 @@ import { useQuery } from "@tanstack/react-query"; import React from "react"; import { useConversationId } from "#/hooks/use-conversation-id"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useRuntimeIsReady } from "../use-runtime-is-ready"; export const useConversationConfig = () => { @@ -12,7 +12,7 @@ export const useConversationConfig = () => { queryKey: ["conversation_config", conversationId], queryFn: () => { if (!conversationId) throw new Error("No conversation ID"); - return OpenHands.getRuntimeId(conversationId); + return ConversationService.getRuntimeId(conversationId); }, enabled: runtimeIsReady && !!conversationId, staleTime: 1000 * 60 * 5, // 5 minutes diff --git a/frontend/src/hooks/query/use-conversation-microagents.ts b/frontend/src/hooks/query/use-conversation-microagents.ts index 92b3cab990..027fd90a00 100644 --- a/frontend/src/hooks/query/use-conversation-microagents.ts +++ b/frontend/src/hooks/query/use-conversation-microagents.ts @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { useSelector } from "react-redux"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useConversationId } from "../use-conversation-id"; import { RootState } from "#/store"; import { AgentState } from "#/types/agent-state"; @@ -15,7 +15,7 @@ export const useConversationMicroagents = () => { if (!conversationId) { throw new Error("No conversation ID provided"); } - const data = await OpenHands.getMicroagents(conversationId); + const data = await ConversationService.getMicroagents(conversationId); return data.microagents; }, enabled: diff --git a/frontend/src/hooks/query/use-get-diff.ts b/frontend/src/hooks/query/use-get-diff.ts index 8756e9970f..813474f74a 100644 --- a/frontend/src/hooks/query/use-get-diff.ts +++ b/frontend/src/hooks/query/use-get-diff.ts @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import GitService from "#/api/git-service/git-service.api"; import { GitChangeStatus } from "#/api/open-hands.types"; import { useConversationId } from "#/hooks/use-conversation-id"; @@ -14,7 +14,7 @@ export const useGitDiff = (config: UseGetDiffConfig) => { return useQuery({ queryKey: ["file_diff", conversationId, config.filePath, config.type], - queryFn: () => OpenHands.getGitChangeDiff(conversationId, config.filePath), + queryFn: () => GitService.getGitChangeDiff(conversationId, config.filePath), enabled: config.enabled, staleTime: 1000 * 60 * 5, // 5 minutes gcTime: 1000 * 60 * 15, // 15 minutes diff --git a/frontend/src/hooks/query/use-get-git-changes.ts b/frontend/src/hooks/query/use-get-git-changes.ts index 55ab59122b..92643e703d 100644 --- a/frontend/src/hooks/query/use-get-git-changes.ts +++ b/frontend/src/hooks/query/use-get-git-changes.ts @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import React from "react"; -import OpenHands from "#/api/open-hands"; +import GitService from "#/api/git-service/git-service.api"; import { useConversationId } from "#/hooks/use-conversation-id"; import { GitChange } from "#/api/open-hands.types"; import { useRuntimeIsReady } from "#/hooks/use-runtime-is-ready"; @@ -13,7 +13,7 @@ export const useGetGitChanges = () => { const result = useQuery({ queryKey: ["file_changes", conversationId], - queryFn: () => OpenHands.getGitChanges(conversationId), + queryFn: () => GitService.getGitChanges(conversationId), retry: false, staleTime: 1000 * 60 * 5, // 5 minutes gcTime: 1000 * 60 * 15, // 15 minutes diff --git a/frontend/src/hooks/query/use-get-microagents.ts b/frontend/src/hooks/query/use-get-microagents.ts index 097473b170..67a4fecfd1 100644 --- a/frontend/src/hooks/query/use-get-microagents.ts +++ b/frontend/src/hooks/query/use-get-microagents.ts @@ -1,13 +1,14 @@ import { useQuery } from "@tanstack/react-query"; import { useConversationId } from "../use-conversation-id"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; export const useGetMicroagents = (microagentDirectory: string) => { const { conversationId } = useConversationId(); return useQuery({ queryKey: ["files", "microagents", conversationId, microagentDirectory], - queryFn: () => OpenHands.getFiles(conversationId!, microagentDirectory), + queryFn: () => + ConversationService.getFiles(conversationId!, microagentDirectory), enabled: !!conversationId, select: (data) => data.map((fileName) => fileName.replace(microagentDirectory, "")), diff --git a/frontend/src/hooks/query/use-microagent-prompt.ts b/frontend/src/hooks/query/use-microagent-prompt.ts index ac9275a18e..c728e5f795 100644 --- a/frontend/src/hooks/query/use-microagent-prompt.ts +++ b/frontend/src/hooks/query/use-microagent-prompt.ts @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useConversationId } from "../use-conversation-id"; export const useMicroagentPrompt = (eventId: number) => { @@ -7,7 +7,8 @@ export const useMicroagentPrompt = (eventId: number) => { return useQuery({ queryKey: ["memory", "prompt", conversationId, eventId], - queryFn: () => OpenHands.getMicroagentPrompt(conversationId!, eventId), + queryFn: () => + ConversationService.getMicroagentPrompt(conversationId!, eventId), enabled: !!conversationId, staleTime: 1000 * 60 * 5, // 5 minutes gcTime: 1000 * 60 * 15, // 15 minutes diff --git a/frontend/src/hooks/query/use-paginated-conversations.ts b/frontend/src/hooks/query/use-paginated-conversations.ts index e4e301e0d9..8d4a7a693a 100644 --- a/frontend/src/hooks/query/use-paginated-conversations.ts +++ b/frontend/src/hooks/query/use-paginated-conversations.ts @@ -1,5 +1,5 @@ import { useInfiniteQuery } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useIsAuthed } from "./use-is-authed"; export const usePaginatedConversations = (limit: number = 20) => { @@ -8,7 +8,7 @@ export const usePaginatedConversations = (limit: number = 20) => { return useInfiniteQuery({ queryKey: ["user", "conversations", "paginated", limit], queryFn: ({ pageParam }) => - OpenHands.getUserConversations(limit, pageParam), + ConversationService.getUserConversations(limit, pageParam), enabled: !!userIsAuthenticated, getNextPageParam: (lastPage) => lastPage.next_page_id, initialPageParam: undefined as string | undefined, diff --git a/frontend/src/hooks/query/use-search-conversations.ts b/frontend/src/hooks/query/use-search-conversations.ts index 0a47316705..73f84f0990 100644 --- a/frontend/src/hooks/query/use-search-conversations.ts +++ b/frontend/src/hooks/query/use-search-conversations.ts @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; export const useSearchConversations = ( selectedRepository?: string, @@ -16,7 +16,7 @@ export const useSearchConversations = ( limit, ], queryFn: () => - OpenHands.searchConversations( + ConversationService.searchConversations( selectedRepository, conversationTrigger, limit, diff --git a/frontend/src/hooks/query/use-user-conversation.ts b/frontend/src/hooks/query/use-user-conversation.ts index 8c371e10bc..fbae346356 100644 --- a/frontend/src/hooks/query/use-user-conversation.ts +++ b/frontend/src/hooks/query/use-user-conversation.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Query, useQuery } from "@tanstack/react-query"; import { AxiosError } from "axios"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { Conversation } from "#/api/open-hands.types"; const FIVE_MINUTES = 1000 * 60 * 5; @@ -22,7 +22,7 @@ export const useUserConversation = ( useQuery({ queryKey: ["user", "conversation", cid], queryFn: async () => { - const conversation = await OpenHands.getConversation(cid!); + const conversation = await ConversationService.getConversation(cid!); return conversation; }, enabled: !!cid, diff --git a/frontend/src/hooks/query/use-vscode-url.ts b/frontend/src/hooks/query/use-vscode-url.ts index d3a40f9b7b..8b0e74df27 100644 --- a/frontend/src/hooks/query/use-vscode-url.ts +++ b/frontend/src/hooks/query/use-vscode-url.ts @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { useTranslation } from "react-i18next"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useConversationId } from "#/hooks/use-conversation-id"; import { I18nKey } from "#/i18n/declaration"; import { transformVSCodeUrl } from "#/utils/vscode-url-helper"; @@ -21,7 +21,7 @@ export const useVSCodeUrl = () => { queryKey: ["vscode_url", conversationId], queryFn: async () => { if (!conversationId) throw new Error("No conversation ID"); - const data = await OpenHands.getVSCodeUrl(conversationId); + const data = await ConversationService.getVSCodeUrl(conversationId); if (data.vscode_url) { return { url: transformVSCodeUrl(data.vscode_url), diff --git a/frontend/src/hooks/use-conversation-name-context-menu.ts b/frontend/src/hooks/use-conversation-name-context-menu.ts index 3a6ef49daa..2dc493d5b2 100644 --- a/frontend/src/hooks/use-conversation-name-context-menu.ts +++ b/frontend/src/hooks/use-conversation-name-context-menu.ts @@ -8,7 +8,7 @@ import { transformVSCodeUrl } from "#/utils/vscode-url-helper"; import { RootState } from "#/store"; import { isSystemMessage } from "#/types/core/guards"; import { ConversationStatus } from "#/types/conversation-status"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useDeleteConversation } from "./mutation/use-delete-conversation"; import { useStopConversation } from "./mutation/use-stop-conversation"; import { useGetTrajectory } from "./mutation/use-get-trajectory"; @@ -129,7 +129,7 @@ export function useConversationNameContextMenu({ // Fetch the VS Code URL from the API if (conversationId) { try { - const data = await OpenHands.getVSCodeUrl(conversationId); + const data = await ConversationService.getVSCodeUrl(conversationId); if (data.vscode_url) { const transformedUrl = transformVSCodeUrl(data.vscode_url); if (transformedUrl) { diff --git a/frontend/src/hooks/use-create-conversation-and-subscribe-multiple.ts b/frontend/src/hooks/use-create-conversation-and-subscribe-multiple.ts index 017e3bbdb7..e986d53052 100644 --- a/frontend/src/hooks/use-create-conversation-and-subscribe-multiple.ts +++ b/frontend/src/hooks/use-create-conversation-and-subscribe-multiple.ts @@ -7,7 +7,7 @@ import { useUserProviders } from "./use-user-providers"; import { useConversationSubscriptions } from "#/context/conversation-subscriptions-provider"; import { Provider } from "#/types/settings"; import { CreateMicroagent, Conversation } from "#/api/open-hands.types"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { renderConversationStartingToast } from "#/components/features/chat/microagent/microagent-status-toast"; interface ConversationData { @@ -45,7 +45,7 @@ export const useCreateConversationAndSubscribeMultiple = () => { const conversationQueries = useQueries({ queries: conversationIdsToWatch.map((conversationId) => ({ queryKey: ["conversation-ready-poll", conversationId], - queryFn: () => OpenHands.getConversation(conversationId), + queryFn: () => ConversationService.getConversation(conversationId), enabled: !!conversationId, refetchInterval: (query: Query) => { const status = query.state.data?.status; diff --git a/frontend/src/routes/conversation.tsx b/frontend/src/routes/conversation.tsx index dd26972027..d4f7933a06 100644 --- a/frontend/src/routes/conversation.tsx +++ b/frontend/src/routes/conversation.tsx @@ -19,7 +19,7 @@ import { useActiveConversation } from "#/hooks/query/use-active-conversation"; import { displayErrorToast } from "#/utils/custom-toast-handlers"; import { useDocumentTitleFromState } from "#/hooks/use-document-title-from-state"; -import OpenHands from "#/api/open-hands"; +import ConversationService from "#/api/conversation-service/conversation-service.api"; import { useIsAuthed } from "#/hooks/query/use-is-authed"; import { ConversationSubscriptionsProvider } from "#/context/conversation-subscriptions-provider"; import { useUserProviders } from "#/hooks/use-user-providers"; @@ -53,9 +53,10 @@ function AppContent() { navigate("/"); } else if (conversation?.status === "STOPPED") { // start the conversation if the state is stopped on initial load - OpenHands.startConversation(conversation.conversation_id, providers).then( - () => refetch(), - ); + ConversationService.startConversation( + conversation.conversation_id, + providers, + ).then(() => refetch()); } }, [conversation?.conversation_id, isFetched, isAuthed, providers]);