mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
feat(frontend): integrate with the updated get microagents API for the microagent management page. (#10010)
This commit is contained in:
parent
b28e0533e0
commit
953902dcce
@ -105,22 +105,12 @@ describe("MicroagentManagement", () => {
|
||||
const mockMicroagents: RepositoryMicroagent[] = [
|
||||
{
|
||||
name: "test-microagent-1",
|
||||
type: "repo",
|
||||
content: "Test microagent content 1",
|
||||
triggers: ["test", "microagent"],
|
||||
inputs: [],
|
||||
tools: [],
|
||||
created_at: "2021-10-01T12:00:00Z",
|
||||
git_provider: "github",
|
||||
path: ".openhands/microagents/test-microagent-1",
|
||||
},
|
||||
{
|
||||
name: "test-microagent-2",
|
||||
type: "knowledge",
|
||||
content: "Test microagent content 2",
|
||||
triggers: ["knowledge", "test"],
|
||||
inputs: [],
|
||||
tools: [],
|
||||
created_at: "2021-10-02T12:00:00Z",
|
||||
git_provider: "github",
|
||||
path: ".openhands/microagents/test-microagent-2",
|
||||
@ -173,6 +163,13 @@ describe("MicroagentManagement", () => {
|
||||
vi.spyOn(OpenHands, "searchConversations").mockResolvedValue([
|
||||
...mockConversations,
|
||||
]);
|
||||
// Setup default mock for getRepositoryMicroagentContent
|
||||
vi.spyOn(OpenHands, "getRepositoryMicroagentContent").mockResolvedValue({
|
||||
content: "Original microagent content for testing updates",
|
||||
path: ".openhands/microagents/update-test-microagent",
|
||||
git_provider: "github",
|
||||
triggers: ["test", "update"],
|
||||
});
|
||||
});
|
||||
|
||||
it("should render the microagent management page", async () => {
|
||||
@ -1187,17 +1184,6 @@ describe("MicroagentManagement", () => {
|
||||
|
||||
expect(conversation1).toBeInTheDocument();
|
||||
expect(conversation2).toBeInTheDocument();
|
||||
|
||||
// Check that created dates are displayed for conversations (there are multiple elements with the same text)
|
||||
const createdDates = screen.getAllByText(
|
||||
/COMMON\$CREATED_ON.*10\/01\/2021/,
|
||||
);
|
||||
expect(createdDates.length).toBeGreaterThan(0);
|
||||
|
||||
const createdDates2 = screen.getAllByText(
|
||||
/COMMON\$CREATED_ON.*10\/02\/2021/,
|
||||
);
|
||||
expect(createdDates2.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should handle multiple repository expansions with conversations", async () => {
|
||||
@ -1475,11 +1461,6 @@ describe("MicroagentManagement", () => {
|
||||
describe("MicroagentManagementMain", () => {
|
||||
const mockRepositoryMicroagent: RepositoryMicroagent = {
|
||||
name: "test-microagent",
|
||||
type: "repo",
|
||||
content: "Test microagent content",
|
||||
triggers: ["test", "microagent"],
|
||||
inputs: [],
|
||||
tools: [],
|
||||
created_at: "2021-10-01T12:00:00Z",
|
||||
git_provider: "github",
|
||||
path: ".openhands/microagents/test-microagent",
|
||||
@ -1820,11 +1801,6 @@ describe("MicroagentManagement", () => {
|
||||
it("should handle microagent with all required properties", async () => {
|
||||
const completeMicroagent: RepositoryMicroagent = {
|
||||
name: "complete-microagent",
|
||||
type: "knowledge",
|
||||
content: "Complete microagent content with all properties",
|
||||
triggers: ["complete", "test"],
|
||||
inputs: ["input1", "input2"],
|
||||
tools: ["tool1", "tool2"],
|
||||
created_at: "2021-10-01T12:00:00Z",
|
||||
git_provider: "github",
|
||||
path: ".openhands/microagents/complete-microagent",
|
||||
@ -1874,11 +1850,6 @@ describe("MicroagentManagement", () => {
|
||||
describe("Update microagent functionality", () => {
|
||||
const mockMicroagentForUpdate: RepositoryMicroagent = {
|
||||
name: "update-test-microagent",
|
||||
type: "repo",
|
||||
content: "Original microagent content for testing updates",
|
||||
triggers: ["original", "test"],
|
||||
inputs: [],
|
||||
tools: [],
|
||||
created_at: "2021-10-01T12:00:00Z",
|
||||
git_provider: "github",
|
||||
path: ".openhands/microagents/update-test-microagent",
|
||||
@ -1999,11 +1970,13 @@ describe("MicroagentManagement", () => {
|
||||
},
|
||||
});
|
||||
|
||||
// Check that the form fields are populated with existing data
|
||||
const queryInput = screen.getByTestId("query-input");
|
||||
expect(queryInput).toHaveValue(
|
||||
"Original microagent content for testing updates",
|
||||
);
|
||||
// Wait for the content to be loaded and form fields to be populated
|
||||
await waitFor(() => {
|
||||
const queryInput = screen.getByTestId("query-input");
|
||||
expect(queryInput).toHaveValue(
|
||||
"Original microagent content for testing updates",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle update microagent form submission", async () => {
|
||||
@ -2207,12 +2180,16 @@ describe("MicroagentManagement", () => {
|
||||
|
||||
it("should handle update modal with microagent that has no content", async () => {
|
||||
const user = userEvent.setup();
|
||||
const microagentWithoutContent = {
|
||||
...mockMicroagentForUpdate,
|
||||
content: "",
|
||||
};
|
||||
|
||||
// Render with update modal visible and microagent without content
|
||||
// Mock the content API to return empty content for this test
|
||||
vi.spyOn(OpenHands, "getRepositoryMicroagentContent").mockResolvedValue({
|
||||
content: "",
|
||||
path: ".openhands/microagents/update-test-microagent",
|
||||
git_provider: "github",
|
||||
triggers: [],
|
||||
});
|
||||
|
||||
// Render with update modal visible and microagent
|
||||
renderWithProviders(<RouterStub />, {
|
||||
preloadedState: {
|
||||
metrics: {
|
||||
@ -2222,7 +2199,7 @@ describe("MicroagentManagement", () => {
|
||||
},
|
||||
microagentManagement: {
|
||||
selectedMicroagentItem: {
|
||||
microagent: microagentWithoutContent,
|
||||
microagent: mockMicroagentForUpdate,
|
||||
conversation: undefined,
|
||||
},
|
||||
addMicroagentModalVisible: false,
|
||||
@ -2243,19 +2220,25 @@ describe("MicroagentManagement", () => {
|
||||
},
|
||||
});
|
||||
|
||||
// Check that the form field is empty
|
||||
const queryInput = screen.getByTestId("query-input");
|
||||
expect(queryInput).toHaveValue("");
|
||||
// Wait for the content to be loaded and check that the form field is empty
|
||||
await waitFor(() => {
|
||||
const queryInput = screen.getByTestId("query-input");
|
||||
expect(queryInput).toHaveValue("");
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle update modal with microagent that has no triggers", async () => {
|
||||
const user = userEvent.setup();
|
||||
const microagentWithoutTriggers = {
|
||||
...mockMicroagentForUpdate,
|
||||
triggers: [],
|
||||
};
|
||||
|
||||
// Render with update modal visible and microagent without triggers
|
||||
// Mock the content API to return content without triggers for this test
|
||||
vi.spyOn(OpenHands, "getRepositoryMicroagentContent").mockResolvedValue({
|
||||
content: "Original microagent content for testing updates",
|
||||
path: ".openhands/microagents/update-test-microagent",
|
||||
git_provider: "github",
|
||||
triggers: [],
|
||||
});
|
||||
|
||||
// Render with update modal visible and microagent
|
||||
renderWithProviders(<RouterStub />, {
|
||||
preloadedState: {
|
||||
metrics: {
|
||||
@ -2265,7 +2248,7 @@ describe("MicroagentManagement", () => {
|
||||
},
|
||||
microagentManagement: {
|
||||
selectedMicroagentItem: {
|
||||
microagent: microagentWithoutTriggers,
|
||||
microagent: mockMicroagentForUpdate,
|
||||
conversation: undefined,
|
||||
},
|
||||
addMicroagentModalVisible: false,
|
||||
@ -2397,11 +2380,6 @@ describe("MicroagentManagement", () => {
|
||||
getRepositoryMicroagentsSpy.mockResolvedValue([
|
||||
{
|
||||
name: "test-microagent",
|
||||
type: "repo",
|
||||
content: "Test content",
|
||||
triggers: [],
|
||||
inputs: [],
|
||||
tools: [],
|
||||
created_at: "2021-10-01",
|
||||
git_provider: "github",
|
||||
path: ".openhands/microagents/test",
|
||||
@ -2486,11 +2464,6 @@ describe("MicroagentManagement", () => {
|
||||
describe("Learn something new button functionality", () => {
|
||||
const mockMicroagentForLearn: RepositoryMicroagent = {
|
||||
name: "learn-test-microagent",
|
||||
type: "repo",
|
||||
content: "Test microagent content for learn functionality",
|
||||
triggers: ["learn", "test"],
|
||||
inputs: [],
|
||||
tools: [],
|
||||
created_at: "2021-10-01T12:00:00Z",
|
||||
git_provider: "github",
|
||||
path: ".openhands/microagents/learn-test-microagent",
|
||||
@ -2586,6 +2559,14 @@ describe("MicroagentManagement", () => {
|
||||
it("should populate form fields with current microagent data when learn button is clicked", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
// Mock the content API to return the expected content for this test
|
||||
vi.spyOn(OpenHands, "getRepositoryMicroagentContent").mockResolvedValue({
|
||||
content: "Test microagent content for learn functionality",
|
||||
path: ".openhands/microagents/learn-test-microagent",
|
||||
git_provider: "github",
|
||||
triggers: ["learn", "test"],
|
||||
});
|
||||
|
||||
// Render with selected microagent
|
||||
renderWithProviders(<RouterStub />, {
|
||||
preloadedState: {
|
||||
@ -2626,21 +2607,27 @@ describe("MicroagentManagement", () => {
|
||||
expect(screen.getByTestId("add-microagent-modal")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Check that the form fields are populated with current microagent data
|
||||
const queryInput = screen.getByTestId("query-input");
|
||||
expect(queryInput).toHaveValue(
|
||||
"Test microagent content for learn functionality",
|
||||
);
|
||||
// Wait for the content to be loaded and form to be populated
|
||||
await waitFor(() => {
|
||||
const queryInput = screen.getByTestId("query-input");
|
||||
expect(queryInput).toHaveValue(
|
||||
"Test microagent content for learn functionality",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle learn button click with microagent that has no content", async () => {
|
||||
const user = userEvent.setup();
|
||||
const microagentWithoutContent = {
|
||||
...mockMicroagentForLearn,
|
||||
content: "",
|
||||
};
|
||||
|
||||
// Render with selected microagent without content
|
||||
// Mock the content API to return empty content for this test
|
||||
vi.spyOn(OpenHands, "getRepositoryMicroagentContent").mockResolvedValue({
|
||||
content: "",
|
||||
path: ".openhands/microagents/learn-test-microagent",
|
||||
git_provider: "github",
|
||||
triggers: [],
|
||||
});
|
||||
|
||||
// Render with selected microagent
|
||||
renderWithProviders(<RouterStub />, {
|
||||
preloadedState: {
|
||||
metrics: {
|
||||
@ -2650,7 +2637,7 @@ describe("MicroagentManagement", () => {
|
||||
},
|
||||
microagentManagement: {
|
||||
selectedMicroagentItem: {
|
||||
microagent: microagentWithoutContent,
|
||||
microagent: mockMicroagentForLearn,
|
||||
conversation: undefined,
|
||||
},
|
||||
addMicroagentModalVisible: false,
|
||||
@ -2680,19 +2667,25 @@ describe("MicroagentManagement", () => {
|
||||
expect(screen.getByTestId("add-microagent-modal")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Check that the form field is empty
|
||||
const queryInput = screen.getByTestId("query-input");
|
||||
expect(queryInput).toHaveValue("");
|
||||
// Wait for the content to be loaded and check that the form field is empty
|
||||
await waitFor(() => {
|
||||
const queryInput = screen.getByTestId("query-input");
|
||||
expect(queryInput).toHaveValue("");
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle learn button click with microagent that has no triggers", async () => {
|
||||
const user = userEvent.setup();
|
||||
const microagentWithoutTriggers = {
|
||||
...mockMicroagentForLearn,
|
||||
triggers: [],
|
||||
};
|
||||
|
||||
// Render with selected microagent without triggers
|
||||
// Mock the content API to return content without triggers for this test
|
||||
vi.spyOn(OpenHands, "getRepositoryMicroagentContent").mockResolvedValue({
|
||||
content: "Test microagent content for learn functionality",
|
||||
path: ".openhands/microagents/learn-test-microagent",
|
||||
git_provider: "github",
|
||||
triggers: [],
|
||||
});
|
||||
|
||||
// Render with selected microagent
|
||||
renderWithProviders(<RouterStub />, {
|
||||
preloadedState: {
|
||||
metrics: {
|
||||
@ -2702,7 +2695,7 @@ describe("MicroagentManagement", () => {
|
||||
},
|
||||
microagentManagement: {
|
||||
selectedMicroagentItem: {
|
||||
microagent: microagentWithoutTriggers,
|
||||
microagent: mockMicroagentForLearn,
|
||||
conversation: undefined,
|
||||
},
|
||||
addMicroagentModalVisible: false,
|
||||
|
||||
@ -14,6 +14,7 @@ import {
|
||||
GetMicroagentsResponse,
|
||||
GetMicroagentPromptResponse,
|
||||
CreateMicroagent,
|
||||
MicroagentContentResponse,
|
||||
} from "./open-hands.types";
|
||||
import { openHands } from "./open-hands-axios";
|
||||
import { ApiSettings, PostApiSettings, Provider } from "#/types/settings";
|
||||
@ -524,7 +525,7 @@ class OpenHands {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the available microagents for a specific repository
|
||||
* Get the available microagents for a repository
|
||||
* @param owner The repository owner
|
||||
* @param repo The repository name
|
||||
* @returns The available microagents for the repository
|
||||
@ -539,6 +540,27 @@ class OpenHands {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 getRepositoryMicroagentContent(
|
||||
owner: string,
|
||||
repo: string,
|
||||
filePath: string,
|
||||
): Promise<MicroagentContentResponse> {
|
||||
const { data } = await openHands.get<MicroagentContentResponse>(
|
||||
`/api/user/repository/${owner}/${repo}/microagents/content`,
|
||||
{
|
||||
params: { file_path: filePath },
|
||||
},
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
static async getMicroagentPrompt(
|
||||
conversationId: string,
|
||||
eventId: number,
|
||||
|
||||
@ -147,3 +147,10 @@ export interface CreateMicroagent {
|
||||
git_provider?: Provider;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export interface MicroagentContentResponse {
|
||||
content: string;
|
||||
path: string;
|
||||
git_provider: Provider;
|
||||
triggers: string[];
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ import { useMemo } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { I18nKey } from "#/i18n/declaration";
|
||||
import { formatDateMMDDYYYY } from "#/utils/format-time-delta";
|
||||
import { RepositoryMicroagent } from "#/types/microagent-management";
|
||||
import { Conversation } from "#/api/open-hands.types";
|
||||
import {
|
||||
@ -38,22 +37,6 @@ export function MicroagentManagementMicroagentCard({
|
||||
pr_number: prNumber,
|
||||
} = conversation ?? {};
|
||||
|
||||
// Format the repository URL to point to the microagent file
|
||||
const microagentFilePath = microagent
|
||||
? `.openhands/microagents/${microagent.name}`
|
||||
: "";
|
||||
|
||||
// Format the createdAt date using MM/DD/YYYY format
|
||||
const formattedCreatedAt = useMemo(() => {
|
||||
if (microagent) {
|
||||
return formatDateMMDDYYYY(new Date(microagent.created_at));
|
||||
}
|
||||
if (conversation) {
|
||||
return formatDateMMDDYYYY(new Date(conversation.created_at));
|
||||
}
|
||||
return "";
|
||||
}, [microagent, conversation]);
|
||||
|
||||
const hasPr = !!(prNumber && prNumber.length > 0);
|
||||
|
||||
// Helper function to get status text
|
||||
@ -131,12 +114,9 @@ export function MicroagentManagementMicroagentCard({
|
||||
<div className="text-white text-[16px] font-semibold">{cardTitle}</div>
|
||||
{!!microagent && (
|
||||
<div className="text-white text-sm font-normal">
|
||||
{microagentFilePath}
|
||||
{microagent.path}
|
||||
</div>
|
||||
)}
|
||||
<div className="text-white text-sm font-normal">
|
||||
{t(I18nKey.COMMON$CREATED_ON)} {formattedCreatedAt}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -8,11 +8,12 @@ import { BrandButton } from "../settings/brand-button";
|
||||
import { I18nKey } from "#/i18n/declaration";
|
||||
import { RootState } from "#/store";
|
||||
import XIcon from "#/icons/x.svg?react";
|
||||
import { cn } from "#/utils/utils";
|
||||
import { cn, extractRepositoryInfo } from "#/utils/utils";
|
||||
import { BadgeInput } from "#/components/shared/inputs/badge-input";
|
||||
import { MicroagentFormData } from "#/types/microagent-management";
|
||||
import { Branch, GitRepository } from "#/types/git";
|
||||
import { useRepositoryBranches } from "#/hooks/query/use-repository-branches";
|
||||
import { useRepositoryMicroagentContent } from "#/hooks/query/use-repository-microagent-content";
|
||||
import {
|
||||
BranchDropdown,
|
||||
BranchLoadingState,
|
||||
@ -51,13 +52,23 @@ export function MicroagentManagementUpsertMicroagentModal({
|
||||
// Add a ref to track if the branch was manually cleared by the user
|
||||
const branchManuallyClearedRef = useRef<boolean>(false);
|
||||
|
||||
// Extract owner and repo from full_name for content API
|
||||
const { owner, repo, filePath } = extractRepositoryInfo(
|
||||
selectedRepository,
|
||||
microagent,
|
||||
);
|
||||
|
||||
// Fetch microagent content when updating
|
||||
const { data: microagentContentData, isLoading: isLoadingContent } =
|
||||
useRepositoryMicroagentContent(owner, repo, filePath, true);
|
||||
|
||||
// Populate form fields with existing microagent data when updating
|
||||
useEffect(() => {
|
||||
if (isUpdate && microagent) {
|
||||
setQuery(microagent.content);
|
||||
setTriggers(microagent.triggers || []);
|
||||
if (isUpdate && microagentContentData) {
|
||||
setQuery(microagentContentData.content);
|
||||
setTriggers(microagentContentData.triggers || []);
|
||||
}
|
||||
}, [isUpdate, microagent]);
|
||||
}, [isUpdate, microagentContentData]);
|
||||
|
||||
const {
|
||||
data: branches,
|
||||
@ -294,10 +305,11 @@ export function MicroagentManagementUpsertMicroagentModal({
|
||||
isLoading ||
|
||||
isLoadingBranches ||
|
||||
!selectedBranch ||
|
||||
isBranchesError
|
||||
isBranchesError ||
|
||||
(isUpdate && isLoadingContent) // Disable while loading content for updates
|
||||
}
|
||||
>
|
||||
{isLoading || isLoadingBranches
|
||||
{isLoading || isLoadingBranches || (isUpdate && isLoadingContent)
|
||||
? t(I18nKey.HOME$LOADING)
|
||||
: t(I18nKey.MICROAGENT$LAUNCH)}
|
||||
</BrandButton>
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Spinner } from "@heroui/react";
|
||||
import { useSelector } from "react-redux";
|
||||
import Markdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
@ -7,8 +9,12 @@ import { ul, ol } from "../markdown/list";
|
||||
import { paragraph } from "../markdown/paragraph";
|
||||
import { anchor } from "../markdown/anchor";
|
||||
import { RootState } from "#/store";
|
||||
import { useRepositoryMicroagentContent } from "#/hooks/query/use-repository-microagent-content";
|
||||
import { I18nKey } from "#/i18n/declaration";
|
||||
import { extractRepositoryInfo } from "#/utils/utils";
|
||||
|
||||
export function MicroagentManagementViewMicroagentContent() {
|
||||
const { t } = useTranslation();
|
||||
const { selectedMicroagentItem } = useSelector(
|
||||
(state: RootState) => state.microagentManagement,
|
||||
);
|
||||
@ -19,55 +25,49 @@ export function MicroagentManagementViewMicroagentContent() {
|
||||
|
||||
const { microagent } = selectedMicroagentItem ?? {};
|
||||
|
||||
const transformMicroagentContent = (): string => {
|
||||
if (!microagent) {
|
||||
return "";
|
||||
}
|
||||
// Extract owner and repo from full_name (e.g., "owner/repo")
|
||||
const { owner, repo, filePath } = extractRepositoryInfo(
|
||||
selectedRepository,
|
||||
microagent,
|
||||
);
|
||||
|
||||
// If no triggers exist, return the content as-is
|
||||
if (!microagent.triggers || microagent.triggers.length === 0) {
|
||||
return microagent.content;
|
||||
}
|
||||
|
||||
// Create the triggers frontmatter
|
||||
const triggersFrontmatter = `
|
||||
---
|
||||
|
||||
triggers:
|
||||
${microagent.triggers.map((trigger) => ` - ${trigger}`).join("\n")}
|
||||
|
||||
---
|
||||
`;
|
||||
|
||||
// Prepend the frontmatter to the content
|
||||
return `
|
||||
${triggersFrontmatter}
|
||||
|
||||
${microagent.content}
|
||||
`;
|
||||
};
|
||||
// Fetch microagent content using the new API
|
||||
const {
|
||||
data: microagentData,
|
||||
isLoading,
|
||||
error,
|
||||
} = useRepositoryMicroagentContent(owner, repo, filePath, true);
|
||||
|
||||
if (!microagent || !selectedRepository) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Transform the content to include triggers frontmatter if applicable
|
||||
const transformedContent = transformMicroagentContent();
|
||||
|
||||
return (
|
||||
<div className="w-full h-full p-6 bg-[#ffffff1a] rounded-2xl text-white text-sm">
|
||||
<Markdown
|
||||
components={{
|
||||
code,
|
||||
ul,
|
||||
ol,
|
||||
a: anchor,
|
||||
p: paragraph,
|
||||
}}
|
||||
remarkPlugins={[remarkGfm, remarkBreaks]}
|
||||
>
|
||||
{transformedContent}
|
||||
</Markdown>
|
||||
{isLoading && (
|
||||
<div className="flex items-center justify-center w-full h-full">
|
||||
<Spinner size="lg" data-testid="loading-microagent-content-spinner" />
|
||||
</div>
|
||||
)}
|
||||
{error && (
|
||||
<div className="flex items-center justify-center w-full h-full">
|
||||
{t(I18nKey.MICROAGENT_MANAGEMENT$ERROR_LOADING_MICROAGENT_CONTENT)}
|
||||
</div>
|
||||
)}
|
||||
{microagentData && !isLoading && !error && (
|
||||
<Markdown
|
||||
components={{
|
||||
code,
|
||||
ul,
|
||||
ol,
|
||||
a: anchor,
|
||||
p: paragraph,
|
||||
}}
|
||||
remarkPlugins={[remarkGfm, remarkBreaks]}
|
||||
>
|
||||
{microagentData.content}
|
||||
</Markdown>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import OpenHands from "#/api/open-hands";
|
||||
|
||||
export const useRepositoryMicroagentContent = (
|
||||
owner: string,
|
||||
repo: string,
|
||||
filePath: string,
|
||||
cacheDisabled: boolean = false,
|
||||
) =>
|
||||
useQuery({
|
||||
queryKey: ["repository", "microagent", "content", owner, repo, filePath],
|
||||
queryFn: () =>
|
||||
OpenHands.getRepositoryMicroagentContent(owner, repo, filePath),
|
||||
enabled: !!owner && !!repo && !!filePath,
|
||||
staleTime: cacheDisabled ? 0 : 1000 * 60 * 5, // 5 minutes
|
||||
gcTime: cacheDisabled ? 0 : 1000 * 60 * 15, // 15 minutes
|
||||
});
|
||||
@ -734,4 +734,5 @@ export enum I18nKey {
|
||||
MICROAGENT_MANAGEMENT$WHAT_YOU_WOULD_LIKE_TO_KNOW_ABOUT_THIS_REPO = "MICROAGENT_MANAGEMENT$WHAT_YOU_WOULD_LIKE_TO_KNOW_ABOUT_THIS_REPO",
|
||||
MICROAGENT_MANAGEMENT$DESCRIBE_WHAT_TO_KNOW_ABOUT_THIS_REPO = "MICROAGENT_MANAGEMENT$DESCRIBE_WHAT_TO_KNOW_ABOUT_THIS_REPO",
|
||||
MICROAGENT_MANAGEMENT$UPDATE_MICROAGENT_MODAL_DESCRIPTION = "MICROAGENT_MANAGEMENT$UPDATE_MICROAGENT_MODAL_DESCRIPTION",
|
||||
MICROAGENT_MANAGEMENT$ERROR_LOADING_MICROAGENT_CONTENT = "MICROAGENT_MANAGEMENT$ERROR_LOADING_MICROAGENT_CONTENT",
|
||||
}
|
||||
|
||||
@ -11742,5 +11742,21 @@
|
||||
"tr": "OpenHands, talimatlarınıza göre mikro ajanı güncelleyecektir.",
|
||||
"de": "OpenHands aktualisiert den Microagenten basierend auf Ihren Anweisungen.",
|
||||
"uk": "OpenHands оновить мікроагента відповідно до ваших інструкцій."
|
||||
},
|
||||
"MICROAGENT_MANAGEMENT$ERROR_LOADING_MICROAGENT_CONTENT": {
|
||||
"en": "Error loading microagent content.",
|
||||
"ja": "マイクロエージェントのコンテンツの読み込み中にエラーが発生しました。",
|
||||
"zh-CN": "加载微代理内容时出错。",
|
||||
"zh-TW": "載入微代理內容時發生錯誤。",
|
||||
"ko-KR": "마이크로에이전트 콘텐츠를 불러오는 중 오류가 발생했습니다.",
|
||||
"no": "Feil ved lasting av mikroagent-innhold.",
|
||||
"it": "Errore durante il caricamento del contenuto del microagente.",
|
||||
"pt": "Erro ao carregar o conteúdo do microagente.",
|
||||
"es": "Error al cargar el contenido del microagente.",
|
||||
"ar": "حدث خطأ أثناء تحميل محتوى الوكيل الدقيق.",
|
||||
"fr": "Erreur lors du chargement du contenu du microagent.",
|
||||
"tr": "Mikro ajan içeriği yüklenirken hata oluştu.",
|
||||
"de": "Fehler beim Laden des Microagent-Inhalts.",
|
||||
"uk": "Помилка під час завантаження вмісту мікроагента."
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,11 +4,6 @@ export type TabType = "personal" | "repositories" | "organizations";
|
||||
|
||||
export interface RepositoryMicroagent {
|
||||
name: string;
|
||||
type: "repo" | "knowledge";
|
||||
content: string;
|
||||
triggers: string[];
|
||||
inputs: string[];
|
||||
tools: string[];
|
||||
created_at: string;
|
||||
git_provider: string;
|
||||
path: string;
|
||||
|
||||
@ -207,3 +207,22 @@ export const constructMicroagentUrl = (
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract repository owner, repo name, and file path from repository and microagent data
|
||||
* @param selectedRepository The selected repository object with full_name property
|
||||
* @param microagent The microagent object with path property
|
||||
* @returns Object containing owner, repo, and filePath
|
||||
*
|
||||
* @example
|
||||
* const { owner, repo, filePath } = extractRepositoryInfo(selectedRepository, microagent);
|
||||
*/
|
||||
export const extractRepositoryInfo = (
|
||||
selectedRepository: { full_name?: string } | null | undefined,
|
||||
microagent: { path?: string } | null | undefined,
|
||||
) => {
|
||||
const [owner, repo] = selectedRepository?.full_name?.split("/") || [];
|
||||
const filePath = microagent?.path || "";
|
||||
|
||||
return { owner, repo, filePath };
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user