diff --git a/frontend/hooks/agentRepository/useRepositoryAgentDetail.ts b/frontend/hooks/agentRepository/useRepositoryAgentDetail.ts index a1f2173e2a..0fd9540398 100644 --- a/frontend/hooks/agentRepository/useRepositoryAgentDetail.ts +++ b/frontend/hooks/agentRepository/useRepositoryAgentDetail.ts @@ -1,8 +1,13 @@ +// Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. All rights reserved. + import { useAgentVersionDetail } from "@/hooks/agent/useAgentVersionDetail"; import { useSkillList } from "@/hooks/agent/useSkillList"; import { useToolList } from "@/hooks/agent/useToolList"; import { useAgentRepositoryListingDetail } from "@/hooks/agentRepository/useAgentRepositoryListings"; -import { mapRepositoryAgentDetail } from "@/lib/myAgentDetail"; +import { + mapOfficialRepositoryDetail, + mapRepositoryAgentDetail, +} from "@/lib/myAgentDetail"; import type { AgentRepositoryListingItem } from "@/types/agentRepository"; export function useRepositoryAgentDetail( @@ -19,18 +24,19 @@ export function useRepositoryAgentDetail( const versionQuery = useAgentVersionDetail( agentId, versionNo, - enabled && repositoryDetail != null + enabled && repositoryDetail != null && repositoryDetail.is_official !== true ); const versionDetail = versionQuery.agentVersionDetail; const { tools } = useToolList({ enabled: enabled && listing != null }); const { skills } = useSkillList({ enabled: enabled && listing != null }); const missingVersion = - repositoryDetail != null && (agentId == null || versionNo == null); - - return { - repositoryDetail, - detail: listing - ? versionDetail && repositoryDetail + repositoryDetail?.is_official !== true && + repositoryDetail != null && + (agentId == null || versionNo == null); + const detail = + listing && repositoryDetail?.is_official === true + ? mapOfficialRepositoryDetail(repositoryDetail, listing.tags) + : listing && versionDetail && repositoryDetail ? mapRepositoryAgentDetail( versionDetail, repositoryDetail, @@ -40,18 +46,24 @@ export function useRepositoryAgentDetail( skills, } ) - : undefined - : null, + : listing + ? undefined + : null; + + return { + repositoryDetail, + detail, isLoading: listing != null && !repositoryQuery.isError && !versionQuery.isError && !missingVersion && - (!repositoryDetail || !versionDetail), + (!repositoryDetail || + (repositoryDetail.is_official !== true && !versionDetail)), isError: repositoryQuery.isError || versionQuery.isError || missingVersion, isFetching: repositoryQuery.isFetching || versionQuery.isFetching, retry: () => { - if (!repositoryDetail || missingVersion) { + if (!repositoryDetail || missingVersion || repositoryDetail.is_official) { return repositoryQuery.refetch(); } return versionQuery.refetch(); diff --git a/frontend/lib/myAgentDetail.ts b/frontend/lib/myAgentDetail.ts index f4158b4b41..ce5959ba07 100644 --- a/frontend/lib/myAgentDetail.ts +++ b/frontend/lib/myAgentDetail.ts @@ -59,10 +59,7 @@ export function mapMyAgentDetail( description: detail.description?.trim() || "", author: detail.author?.trim() || null, authorCasUsername: detail.author_cas_username, - modelName: - detail.model_names?.filter(Boolean).join(", ") || - detail.model_name?.trim() || - null, + modelName: detail.model_name?.trim() || null, versionLabel: detail.version?.version_name?.trim() || null, tools: uniqueNames( detail.tools?.map( @@ -137,3 +134,26 @@ export function mapRepositoryAgentDetail( }, }; } + +export function mapOfficialRepositoryDetail( + detail: AgentRepositoryListingDetail, + tags: string[] = [] +): MyAgentDetailView { + return { + title: detail.display_name?.trim() || detail.name?.trim() || "", + description: detail.description?.trim() || "", + author: detail.author?.trim() || null, + authorCasUsername: detail.author_cas_username, + modelName: detail.model_name?.trim() || null, + versionLabel: detail.version_label?.trim() || null, + tools: uniqueNames(detail.tools ?? []), + skills: [], + knowledgeBases: [], + subAgents: [], + tags: uniqueNames(tags), + repositoryInfo: { + downloads: detail.downloads ?? 0, + createdAt: detail.created_at ?? null, + }, + }; +} diff --git a/frontend/tests/component/casRepositoryIdentity.test.tsx b/frontend/tests/component/casRepositoryIdentity.test.tsx index 4840804b6f..184ec043d1 100644 --- a/frontend/tests/component/casRepositoryIdentity.test.tsx +++ b/frontend/tests/component/casRepositoryIdentity.test.tsx @@ -8,6 +8,7 @@ import { SkillDetail } from "@/components/skill/skill-detail"; import { SkillRepositoryCard } from "../../app/[locale]/skill-space/components/SkillRepositoryCard"; import RepositoryMcpCard from "../../app/[locale]/mcp-space/components/RepositoryMcpCard"; import { + mapOfficialRepositoryDetail, mapMyAgentDetail, mapRepositoryAgentDetail, } from "@/lib/myAgentDetail"; @@ -150,4 +151,31 @@ describe("platform author presentation", () => { expect(detail.author).toBe("Imported Author"); expect(detail.authorCasUsername).toBeUndefined(); }); + + it("maps official repository snapshots without requiring a tenant agent version", () => { + const detail = mapOfficialRepositoryDetail( + { + agent_repository_id: 10, + name: "official-agent", + display_name: "Official Agent", + description: "Official description", + author: "Nexent", + status: "shared", + version_label: "Official", + model_name: "official-model", + tools: ["search"], + }, + ["official"] + ); + + expect(detail).toMatchObject({ + title: "Official Agent", + modelName: "official-model", + tools: ["search"], + skills: [], + knowledgeBases: [], + subAgents: [], + tags: ["official"], + }); + }); });