Skip to content

Commit

Permalink
fix: handle the case when the OPEN_AI_API_KEY is not set
Browse files Browse the repository at this point in the history
  • Loading branch information
Kiryous committed Nov 21, 2024
1 parent cc25aff commit 33e0975
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 10 deletions.
14 changes: 14 additions & 0 deletions keep-ui/app/(keep)/incidents/[id]/chat/page.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@

import { IncidentChat } from "./incident-chat";
import { IncidentDto } from "@/entities/incidents/model";
import { EmptyStateCard } from "@/shared/ui";
import { useConfig } from "@/utils/hooks/useConfig";
import { CopilotKit } from "@copilotkit/react-core";
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";

export function IncidentChatClientPage({
incident,
}: {
incident: IncidentDto;
}) {
const { data: config } = useConfig();
if (config && !config.OPEN_AI_API_KEY_SET) {
return (
<EmptyStateCard
icon={ExclamationTriangleIcon}
title="Chat is not available"
description="The OpenAI API key is not set. Ask your administrator to set it to enable chat."
/>
);
}

return (
<CopilotKit runtimeUrl="/api/copilotkit">
<IncidentChat incident={incident} />
Expand Down
35 changes: 26 additions & 9 deletions keep-ui/app/api/copilotkit/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,37 @@ import {
OpenAIAdapter,
copilotRuntimeNextJSAppRouterEndpoint,
} from "@copilotkit/runtime";
import OpenAI from "openai";
import OpenAI, { OpenAIError } from "openai";
import { NextRequest } from "next/server";

const openai = new OpenAI({
organization: process.env.OPEN_AI_ORGANIZATION_ID,
apiKey: process.env.OPEN_AI_API_KEY,
});
const serviceAdapter = new OpenAIAdapter({ openai });
const runtime = new CopilotRuntime();
function initializeCopilotRuntime() {
try {
const openai = new OpenAI({
organization: process.env.OPEN_AI_ORGANIZATION_ID,
apiKey: process.env.OPEN_AI_API_KEY,
});
const serviceAdapter = new OpenAIAdapter({ openai });
const runtime = new CopilotRuntime();
return { runtime, serviceAdapter };
} catch (error) {
if (error instanceof OpenAIError) {
console.log("Error connecting to OpenAI", error);
} else {
console.error("Error initializing Copilot Runtime", error);
}
return null;
}
}

const runtimeOptions = initializeCopilotRuntime();

export const POST = async (req: NextRequest) => {
if (!runtimeOptions) {
return new Response("Error initializing Copilot Runtime", { status: 500 });
}
const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
runtime,
serviceAdapter,
runtime: runtimeOptions.runtime,
serviceAdapter: runtimeOptions.serviceAdapter,
endpoint: "/api/copilotkit",
});

Expand Down
1 change: 0 additions & 1 deletion keep-ui/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
1 change: 1 addition & 0 deletions keep-ui/shared/lib/server/getConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ export function getConfig() {
POSTHOG_HOST: process.env.POSTHOG_HOST,
SENTRY_DISABLED: process.env.SENTRY_DISABLED,
READ_ONLY: process.env.KEEP_READ_ONLY === "true",
OPEN_AI_API_KEY_SET: !!process.env.OPEN_AI_API_KEY,
};
}
36 changes: 36 additions & 0 deletions keep-ui/shared/ui/EmptyState/EmptyStateCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Card } from "@tremor/react";
import { CircleStackIcon } from "@heroicons/react/24/outline";
import clsx from "clsx";

export function EmptyStateCard({
title,
icon,
description,
className,
children,
}: {
icon?: React.ElementType;
title: string;
description: string;
className?: string;
children?: React.ReactNode;
}) {
const Icon = icon || CircleStackIcon;
return (
<Card className={clsx("sm:mx-auto w-full max-w-5xl", className)}>
<div className="text-center">
<Icon
className="mx-auto h-7 w-7 text-tremor-content-subtle dark:text-dark-tremor-content-subtle"
aria-hidden={true}
/>
<p className="mt-2 text-tremor-default font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong">
{title}
</p>
<p className="text-tremor-default text-tremor-content dark:text-dark-tremor-content">
{description}
</p>
{children}
</div>
</Card>
);
}
1 change: 1 addition & 0 deletions keep-ui/shared/ui/EmptyState/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EmptyStateCard } from "./EmptyStateCard";
1 change: 1 addition & 0 deletions keep-ui/shared/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { TablePagination } from "./TablePagination";
export { TabLinkNavigation, TabNavigationLink } from "./TabLinkNavigation";
export { DateTimeField } from "./DateTimeField";
export { FieldHeader } from "./FieldHeader";
export { EmptyStateCard } from "./EmptyState";
1 change: 1 addition & 0 deletions keep-ui/types/internal-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export interface InternalConfig {
SENTRY_DISABLED: string;
// READ ONLY
READ_ONLY: boolean;
OPEN_AI_API_KEY_SET: boolean;
}

0 comments on commit 33e0975

Please sign in to comment.