import { BookOpenIcon, ChevronUpDownIcon, CpuChipIcon } from "@heroicons/react/20/solid"; import { json, type MetaFunction } from "@remix-run/node"; import { Outlet, useLoaderData, useNavigate, useParams } from "@remix-run/react"; import { type LoaderFunctionArgs } from "@remix-run/server-runtime"; import { CubeSparkleIcon } from "~/assets/icons/CubeSparkleIcon"; import { CodeBlock } from "~/components/code/CodeBlock"; import { InlineCode } from "~/components/code/InlineCode"; import { MainCenteredContainer, PageBody, PageContainer } from "~/components/layout/AppLayout"; import { Badge } from "~/components/primitives/Badge"; import { LinkButton } from "~/components/primitives/Buttons"; import { Header2 } from "~/components/primitives/Headers"; import { InfoPanel } from "~/components/primitives/InfoPanel"; import { NavBar, PageTitle } from "~/components/primitives/PageHeader"; import { Paragraph } from "~/components/primitives/Paragraph"; import { Select, SelectItem } from "~/components/primitives/Select"; import { Table, TableBody, TableCell, TableRow } from "~/components/primitives/Table"; import { $replica } from "~/db.server"; import { useEnvironment } from "~/hooks/useEnvironment"; import { useOrganization } from "~/hooks/useOrganizations"; import { useProject } from "~/hooks/useProject"; import { findProjectBySlug } from "~/models/project.server"; import { findEnvironmentBySlug } from "~/models/runtimeEnvironment.server"; import { playgroundPresenter } from "~/presenters/v3/PlaygroundPresenter.server"; import { RegionsPresenter } from "~/presenters/v3/RegionsPresenter.server"; import { requireUser } from "~/services/session.server"; import { docsPath, EnvironmentParamSchema, v3PlaygroundAgentPath } from "~/utils/pathBuilder"; export const meta: MetaFunction = () => { return [{ title: "Playground | Trigger.dev" }]; }; export const loader = async ({ request, params }: LoaderFunctionArgs) => { const user = await requireUser(request); const { organizationSlug, projectParam, envParam } = EnvironmentParamSchema.parse(params); const project = await findProjectBySlug(organizationSlug, projectParam, user.id); if (!project) { throw new Response(undefined, { status: 404, statusText: "Project not found" }); } const environment = await findEnvironmentBySlug(project.id, envParam, user.id); if (!environment) { throw new Response(undefined, { status: 404, statusText: "Environment not found" }); } const [agents, backgroundWorkers, regionsResult] = await Promise.all([ playgroundPresenter.listAgents({ environmentId: environment.id, environmentType: environment.type, }), $replica.backgroundWorker.findMany({ where: { runtimeEnvironmentId: environment.id }, select: { version: true }, orderBy: { createdAt: "desc" }, take: 20, }), new RegionsPresenter().call({ userId: user.id, projectSlug: projectParam, isAdmin: user.admin || user.isImpersonating, }), ]); return json({ agents, versions: backgroundWorkers.map((w) => w.version), regions: regionsResult.regions, isDev: environment.type === "DEVELOPMENT", }); }; export default function PlaygroundPage() { const { agents } = useLoaderData(); const organization = useOrganization(); const project = useProject(); const environment = useEnvironment(); const params = useParams(); const navigate = useNavigate(); const selectedAgent = params.agentParam ?? ""; const selectedAgentType = (() => { if (!selectedAgent) return null; const agent = agents.find((a) => a.slug === selectedAgent); const config = (agent?.config ?? null) as { type?: string } | null; return config?.type ?? null; })(); if (agents.length === 0) { return ( Agent docs } > Test lets you exercise your AI agents with an interactive chat interface, realtime streaming, and conversation history. Define a chat agent using chat.agent(): { return streamText({ model: openai("gpt-4o"), messages, abortSignal: signal, }); }, });`} showLineNumbers={false} showOpenInModal={false} /> Deploy your project and your agents will appear here ready to test. ); } return ( {selectedAgent ? ( {selectedAgentType && ( {formatAgentType(selectedAgentType)} )} } /> ) : ( )} {selectedAgent ? ( ) : (
Choose an agent to start a conversation {agents.map((agent) => { const path = v3PlaygroundAgentPath( organization, project, environment, agent.slug ); return (
{agent.slug}
); })}
)}
); } function formatAgentType(type: string): string { switch (type) { case "ai-sdk-chat": return "AI SDK Chat"; default: return type; } }