From 6b355e1acfa97db1aa672156938794ce7c4f29f4 Mon Sep 17 00:00:00 2001 From: dotta Date: Wed, 18 Mar 2026 06:47:53 -0500 Subject: [PATCH] Redesign agent instructions tab (formerly Prompts) - Rename Prompts tab to Instructions (with backwards-compatible URL routing) - Update header/subheader text to "Instructions Bundle" / "Configure your agent's behavior with instructions" - Remove standalone legacy prompt warning banner; move warning to deprecated virtual file badge with tooltip - Move mode, root path, and entry file controls into a collapsible "Advanced" section below the file browser - Add help tooltips (?) for mode, root path, and entry file fields - Show full root path in managed mode with copy-to-clipboard icon - Reorder: root path now appears to the left of entry file - Remove HEARTBEAT.md, SOUL.md, TOOLS.md shortcut buttons from file browser - Add key prop to MarkdownEditor to ensure proper re-mount on file selection change Co-Authored-By: Paperclip --- ui/src/pages/AgentDetail.tsx | 255 +++++++++++++++++++++-------------- 1 file changed, 151 insertions(+), 104 deletions(-) diff --git a/ui/src/pages/AgentDetail.tsx b/ui/src/pages/AgentDetail.tsx index dd434ffb..49c7e2bd 100644 --- a/ui/src/pages/AgentDetail.tsx +++ b/ui/src/pages/AgentDetail.tsx @@ -62,7 +62,10 @@ import { ChevronRight, ChevronDown, ArrowLeft, + HelpCircle, } from "lucide-react"; +import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@/components/ui/collapsible"; +import { TooltipProvider } from "@/components/ui/tooltip"; import { Input } from "@/components/ui/input"; import { AgentIcon, AgentIconPicker } from "../components/AgentIconPicker"; import { RunTranscriptView, type TranscriptMode } from "../components/transcript/RunTranscriptView"; @@ -198,10 +201,10 @@ function scrollToContainerBottom(container: ScrollContainer, behavior: ScrollBeh container.scrollTo({ top: container.scrollHeight, behavior }); } -type AgentDetailView = "dashboard" | "prompts" | "configuration" | "skills" | "runs" | "budget"; +type AgentDetailView = "dashboard" | "instructions" | "configuration" | "skills" | "runs" | "budget"; function parseAgentDetailView(value: string | null): AgentDetailView { - if (value === "prompts") return value; + if (value === "instructions" || value === "prompts") return "instructions"; if (value === "configure" || value === "configuration") return "configuration"; if (value === "skills") return "skills"; if (value === "budget") return "budget"; @@ -601,8 +604,8 @@ export function AgentDetail() { return; } const canonicalTab = - activeView === "prompts" - ? "prompts" + activeView === "instructions" + ? "instructions" : activeView === "configuration" ? "configuration" : activeView === "skills" @@ -724,8 +727,8 @@ export function AgentDetail() { if (urlRunId) { crumbs.push({ label: "Runs", href: `/agents/${canonicalAgentRef}/runs` }); crumbs.push({ label: `Run ${urlRunId.slice(0, 8)}` }); - } else if (activeView === "prompts") { - crumbs.push({ label: "Prompts" }); + } else if (activeView === "instructions") { + crumbs.push({ label: "Instructions" }); } else if (activeView === "configuration") { crumbs.push({ label: "Configuration" }); } else if (activeView === "skills") { @@ -761,7 +764,7 @@ export function AgentDetail() { return ; } const isPendingApproval = agent.status === "pending_approval"; - const showConfigActionBar = (activeView === "configuration" || activeView === "prompts") && (configDirty || configSaving); + const showConfigActionBar = (activeView === "configuration" || activeView === "instructions") && (configDirty || configSaving); return (
@@ -888,7 +891,7 @@ export function AgentDetail() { )} - {activeView === "prompts" && ( + {activeView === "instructions" && (

Instructions Bundle

- `AGENTS.md` is the entry file. Sibling files like `HEARTBEAT.md`, `SOUL.md`, `TOOLS.md`, and arbitrary custom files live in the same bundle. + Configure your agent's behavior with instructions

@@ -1742,81 +1745,12 @@ function PromptsTab({
- {(bundle?.legacyPromptTemplateActive || bundle?.legacyBootstrapPromptTemplateActive) && ( -
- Legacy inline prompt state is still present. `promptTemplate` now appears as a deprecated virtual file entry so it is visible without masquerading as the live `AGENTS.md`. -
- )} - {(bundle?.warnings ?? []).map((warning) => (
{warning}
))} -
- - - -
@@ -1847,22 +1781,6 @@ function PromptsTab({ className="font-mono text-sm" />
-
- {["HEARTBEAT.md", "SOUL.md", "TOOLS.md"].map((filePath) => ( - - ))} -
{ const file = bundle?.files.find((entry) => entry.path === node.path); if (!file) return null; + if (file.deprecated) { + return ( + + + + virtual file + + + + Legacy inline prompt — this deprecated virtual file preserves the old promptTemplate content + + + ); + } return ( - - {file.deprecated ? "deprecated" : file.isEntryFile ? "entry" : `${file.size}b`} + + {file.isEntryFile ? "entry" : `${file.size}b`} ); }} /> + + + + + Advanced + + + + +
+ + +
+
+
+
@@ -1937,6 +1983,7 @@ function PromptsTab({ ) : isMarkdown(selectedOrEntryFile) ? ( setDraft(value ?? "")} placeholder="# Agent instructions"