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
8 changes: 4 additions & 4 deletions ui/src/app/agents/[namespace]/[name]/chat/[chatId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"use client";
import { use } from "react";
import ChatInterface from "@/components/chat/ChatInterface";

export default function ChatPageView({ params }: { params: Promise<{ name: string; namespace: string; chatId: string }> }) {
const { name, namespace, chatId } = use(params);
export default async function ChatPageView({ params }: { params: Promise<{ name: string; namespace: string; chatId: string }> }) {
const { name, namespace, chatId } = await params;
const headline = process.env.NEXT_PUBLIC_HEADLINE;

return <ChatInterface
selectedAgentName={name}
selectedNamespace={namespace}
sessionId={chatId}
headline={headline}
/>;
}
10 changes: 5 additions & 5 deletions ui/src/app/agents/[namespace]/[name]/chat/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import ChatInterface from "@/components/chat/ChatInterface";
import { use } from 'react';

// This page component receives props (like params) from the Layout
export default function ChatAgentPage({ params }: { params: Promise<{ name: string, namespace: string }> }) {
const { name, namespace } = use(params);
return <ChatInterface selectedAgentName={name} selectedNamespace={namespace} />;
}
export default async function ChatAgentPage({ params }: { params: Promise<{ name: string, namespace: string }> }) {
const { name, namespace } = await params;
const headline = process.env.NEXT_PUBLIC_HEADLINE;
return <ChatInterface selectedAgentName={name} selectedNamespace={namespace} headline={headline} />;
}
2 changes: 2 additions & 0 deletions ui/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const geistSans = Geist({
subsets: ["latin"],
});

export const dynamic = "force-dynamic";

Comment on lines +17 to +18
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting dynamic = "force-dynamic" in the root layout disables static optimization for the entire application, which may have performance implications. Consider setting this only on the specific pages that need runtime environment variable access instead of globally.

For example, you could add export const dynamic = "force-dynamic" to:

  • ui/src/app/page.tsx (for NEXT_PUBLIC_SUBTITLE)
  • ui/src/app/agents/[namespace]/[name]/chat/page.tsx (for NEXT_PUBLIC_HEADLINE)
  • ui/src/app/agents/[namespace]/[name]/chat/[chatId]/page.tsx (for NEXT_PUBLIC_HEADLINE)

This would allow other pages that don't use these env vars to benefit from static optimization. Note that NEXT_PUBLIC_* env vars are typically available at build time, but if you need them to be configurable at runtime without rebuilding, the current approach or the per-page approach is correct.

Suggested change
export const dynamic = "force-dynamic";

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional. The env vars need to be read at container runtime (not build time) since this is deployed as a Docker image with configurable env vars. force-dynamic is required for that.

Additionally, the sibling PR #1346 (read-only mode) also reads NEXT_PUBLIC_READ_ONLY in the root layout, so force-dynamic needs to be here regardless. Scoping per-page would add boilerplate for negligible gain on a K8s dashboard app.

export const metadata: Metadata = {
title: "kagent.dev",
};
Expand Down
3 changes: 2 additions & 1 deletion ui/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import AgentList from "@/components/AgentList";

export default async function AgentListPage() {
return <AgentList />;
const subtitle = process.env.NEXT_PUBLIC_SUBTITLE;
return <AgentList subtitle={subtitle} />;
}
5 changes: 3 additions & 2 deletions ui/src/components/AgentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Button } from "./ui/button";
import { LoadingState } from "./LoadingState";
import { useAgents } from "./AgentsProvider";

export default function AgentList() {
export default function AgentList({ subtitle }: { subtitle?: string }) {
const { agents , loading, error } = useAgents();

if (error) {
Expand All @@ -22,8 +22,9 @@ export default function AgentList() {
return (
<div className="mt-12 mx-auto max-w-6xl px-6">
<div className="flex justify-between items-center mb-8">
<div className="flex items-center gap-4">
<div className="flex flex-col gap-1">
<h1 className="text-2xl font-bold">Agents</h1>
{subtitle && <p className="text-muted-foreground text-sm">{subtitle}</p>}
</div>
</div>

Expand Down
5 changes: 3 additions & 2 deletions ui/src/components/chat/ChatInterface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ interface ChatInterfaceProps {
selectedNamespace: string;
selectedSession?: Session | null;
sessionId?: string;
headline?: string;
}

export default function ChatInterface({ selectedAgentName, selectedNamespace, selectedSession, sessionId }: ChatInterfaceProps) {
export default function ChatInterface({ selectedAgentName, selectedNamespace, selectedSession, sessionId, headline }: ChatInterfaceProps) {
const router = useRouter();
const containerRef = useRef<HTMLDivElement>(null);
const [currentInputMessage, setCurrentInputMessage] = useState("");
Expand Down Expand Up @@ -379,7 +380,7 @@ export default function ChatInterface({ selectedAgentName, selectedNamespace, se
) : storedMessages.length === 0 && streamingMessages.length === 0 && !isStreaming ? (
<div className="flex items-center justify-center h-full min-h-[50vh]">
<div className="bg-card p-6 rounded-lg shadow-sm border max-w-md text-center">
<h3 className="text-lg font-medium mb-2">Start a conversation</h3>
<h3 className="text-lg font-medium mb-2">{headline || "Start a conversation"}</h3>
<p className="text-muted-foreground">
To begin chatting with the agent, type your message in the input box below.
</p>
Expand Down