Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/components/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ import {
Oauth2CredentialProviderGetScreen,
Oauth2CredentialProviderGetJsonScreen,
} from "../handlers/identity/oauth2-credential-provider/get/screen.tsx";
import { GatewayBrowseScreen } from "../handlers/gateway/screen.tsx";
import { GatewayDetailScreen, GatewayJsonScreen } from "../handlers/gateway/get/screen.tsx";
import { GatewayTargetListScreen } from "../handlers/gateway/target/list/screen.tsx";
import { GatewayTargetJsonScreen } from "../handlers/gateway/target/get/screen.tsx";
import { GatewayConnectorListScreen } from "../handlers/gateway/connector/list/screen.tsx";
import { GatewayConnectorJsonScreen } from "../handlers/gateway/connector/get/screen.tsx";
import { GatewayRuleListScreen } from "../handlers/gateway/rule/list/screen.tsx";
import { GatewayRuleJsonScreen } from "../handlers/gateway/rule/get/screen.tsx";
import { RootScreen, HelpScreen } from "../handlers/screen.tsx";
import type { Context } from "../router";

Expand Down Expand Up @@ -317,6 +325,39 @@ export function Root({ path, ctx, core, queryClient }: RootProps) {
path="agentcore/runtime/invoke/:runtimeId/:qualifier"
element={<RuntimeInvokeScreen ctx={ctx} core={core} />}
/>
<Route path="agentcore/gateway" element={<GatewayBrowseScreen ctx={ctx} core={core} />} />
<Route
path="agentcore/gateway/browse/:gatewayId"
element={<GatewayDetailScreen ctx={ctx} core={core} />}
/>
<Route
path="agentcore/gateway/browse/:gatewayId/json"
element={<GatewayJsonScreen ctx={ctx} core={core} />}
/>
<Route
path="agentcore/gateway/browse/:gatewayId/targets"
element={<GatewayTargetListScreen ctx={ctx} core={core} />}
/>
<Route
path="agentcore/gateway/browse/:gatewayId/targets/:targetId"
element={<GatewayTargetJsonScreen ctx={ctx} core={core} />}
/>
<Route
path="agentcore/gateway/browse/:gatewayId/connectors"
element={<GatewayConnectorListScreen ctx={ctx} core={core} />}
/>
<Route
path="agentcore/gateway/browse/:gatewayId/connectors/:targetId"
element={<GatewayConnectorJsonScreen ctx={ctx} core={core} />}
/>
<Route
path="agentcore/gateway/browse/:gatewayId/rules"
element={<GatewayRuleListScreen ctx={ctx} core={core} />}
/>
<Route
path="agentcore/gateway/browse/:gatewayId/rules/:ruleId"
element={<GatewayRuleJsonScreen ctx={ctx} core={core} />}
/>
<Route path="agentcore/eval" element={<EvalScreen ctx={ctx} core={core} />} />
<Route
path="agentcore/eval/evaluator"
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/data-table/columnWidths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import stringWidth from "string-width";
import { harnessEndpointColumns } from "../../HarnessEndpointPicker";
import { harnessColumns } from "../../HarnessPicker";
import { harnessVersionColumns } from "../../HarnessVersionPicker";
import { memoryColumns } from "../../MemoryPicker";
import { runtimeEndpointColumns } from "../../RuntimeEndpointPicker";
import { runtimeColumns } from "../../RuntimePicker";
import { runtimeVersionColumns } from "../../RuntimeVersionPicker";
import { memoryColumns } from "../../../handlers/memory/list/screen";
import {
computeColumnWidths,
FLEX_MIN_WIDTH,
Expand Down
40 changes: 40 additions & 0 deletions src/handlers/gateway/connector/get/screen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { TargetConfiguration } from "@aws-sdk/client-bedrock-agentcore-control";
import { useQuery } from "@tanstack/react-query";
import { useParams } from "react-router";
import { JsonDetail } from "../../../../components/JsonDetail";
import { InputValidationError } from "../../../../errors";
import type { ScreenProps } from "../../../types";
import { coreOptsFromCtx } from "../../../utils";

function isConnectorTarget(configuration: TargetConfiguration | undefined): boolean {
return (
configuration?.mcp?.connector !== undefined || configuration?.inference?.connector !== undefined
);
}

export function GatewayConnectorJsonScreen(props: ScreenProps) {
const { gatewayId, targetId } = useParams();
const opts = coreOptsFromCtx(props.ctx);
const detail = useQuery({
queryKey: ["gateway-connector", opts.region, gatewayId, targetId],
queryFn: async () => {
const target = await props.core.gateway.getGatewayTarget(gatewayId!, targetId!, opts);
if (!isConnectorTarget(target.targetConfiguration)) {
throw new InputValidationError(`Gateway Target "${targetId}" is not connector-backed`);
}
return target;
},
enabled: gatewayId !== undefined && targetId !== undefined,
});

return (
<JsonDetail
breadcrumb={["agentcore", "gateway", gatewayId ?? "", "connectors", targetId ?? ""]}
isPending={detail.isPending}
error={detail.isError ? (detail.error as Error) : null}
data={detail.data}
loadingLabel="Loading Gateway Connector…"
onRetry={() => void detail.refetch()}
/>
);
}
42 changes: 42 additions & 0 deletions src/handlers/gateway/connector/list/screen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { TargetType } from "@aws-sdk/client-bedrock-agentcore-control";
import { useNavigate, useParams } from "react-router";
import { PaginatedTablePicker } from "../../../../components/PaginatedTablePicker";
import type { ScreenProps } from "../../../types";
import { coreOptsFromCtx } from "../../../utils";
import { targetColumns, targetRow } from "../../target/list/screen";

export function GatewayConnectorListScreen({ ctx, core }: ScreenProps) {
const { gatewayId } = useParams();
const opts = coreOptsFromCtx(ctx);
const navigate = useNavigate();
const encodedGatewayId = encodeURIComponent(gatewayId ?? "");

return (
<PaginatedTablePicker
breadcrumb={["agentcore", "gateway", gatewayId ?? "", "connectors"]}
queryKey={["gateway-connectors", opts.region, gatewayId]}
loadPage={async (token, pageSize) => {
const response = await core.gateway.listGatewayTargets(gatewayId!, token, pageSize, opts);
return {
items: (response.items ?? []).filter(
(target) => target.targetType === TargetType.CONNECTOR,
),
nextToken: response.nextToken,
};
}}
toRow={targetRow}
columns={targetColumns}
getValue={(row) => row.targetId}
onSelect={(targetId) =>
navigate(
`/agentcore/gateway/browse/${encodedGatewayId}/connectors/${encodeURIComponent(targetId)}`,
)
}
onBack={() => navigate(`/agentcore/gateway/browse/${encodedGatewayId}`)}
loadingMessage="Loading Gateway Connectors…"
errorMessage={(error) => `Error: ${error.message}`}
emptyMessage="This Gateway has no Connectors."
emptyPageMessage="No Connectors on this page."
/>
);
}
Loading
Loading