diff --git a/ui/src/components/AgentConfigForm.tsx b/ui/src/components/AgentConfigForm.tsx index 78684cd8..c6e48cd0 100644 --- a/ui/src/components/AgentConfigForm.tsx +++ b/ui/src/components/AgentConfigForm.tsx @@ -65,8 +65,6 @@ type AgentConfigFormProps = { onSaveActionChange?: (save: (() => void) | null) => void; onCancelActionChange?: (cancel: (() => void) | null) => void; hideInlineSave?: boolean; - /** Hide the prompt template field from the Identity section (used when it's shown in a separate Prompts tab). */ - hidePromptTemplate?: boolean; /** "cards" renders each section as heading + bordered card (for settings pages). Default: "inline" (border-b dividers). */ sectionLayout?: "inline" | "cards"; } & ( @@ -475,7 +473,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) { }} /> - {isLocal && !props.hidePromptTemplate && ( + {isLocal && ( <> ; } const isPendingApproval = agent.status === "pending_approval"; - const showConfigActionBar = (activeView === "configuration" || activeView === "prompts") && (configDirty || configSaving); + const showConfigActionBar = activeView === "configuration" && (configDirty || configSaving); return (
@@ -868,9 +861,9 @@ export function AgentDetail() { )} - {activeView === "prompts" && ( - - )} - {activeView === "configuration" && (

API Keys

@@ -1358,7 +1339,6 @@ function ConfigurationTab({ onCancelActionChange, onSavingChange, updatePermissions, - hidePromptTemplate, }: { agent: Agent; companyId?: string; @@ -1367,7 +1347,6 @@ function ConfigurationTab({ onCancelActionChange: (cancel: (() => void) | null) => void; onSavingChange: (saving: boolean) => void; updatePermissions: { mutate: (canCreate: boolean) => void; isPending: boolean }; - hidePromptTemplate?: boolean; }) { const queryClient = useQueryClient(); const [awaitingRefreshAfterSave, setAwaitingRefreshAfterSave] = useState(false); @@ -1422,7 +1401,6 @@ function ConfigurationTab({ onSaveActionChange={onSaveActionChange} onCancelActionChange={onCancelActionChange} hideInlineSave - hidePromptTemplate={hidePromptTemplate} sectionLayout="cards" /> @@ -1449,119 +1427,6 @@ function ConfigurationTab({ ); } -/* ---- Prompts Tab ---- */ - -function PromptsTab({ - agent, - companyId, - onDirtyChange, - onSaveActionChange, - onCancelActionChange, - onSavingChange, -}: { - agent: Agent; - companyId?: string; - onDirtyChange: (dirty: boolean) => void; - onSaveActionChange: (save: (() => void) | null) => void; - onCancelActionChange: (cancel: (() => void) | null) => void; - onSavingChange: (saving: boolean) => void; -}) { - const queryClient = useQueryClient(); - const { selectedCompanyId } = useCompany(); - const [draft, setDraft] = useState(null); - const [awaitingRefresh, setAwaitingRefresh] = useState(false); - const lastAgentRef = useRef(agent); - - const currentValue = String(agent.adapterConfig?.promptTemplate ?? ""); - const displayValue = draft ?? currentValue; - const isDirty = draft !== null && draft !== currentValue; - - const isLocal = - agent.adapterType === "claude_local" || - agent.adapterType === "codex_local" || - agent.adapterType === "opencode_local" || - agent.adapterType === "pi_local" || - agent.adapterType === "hermes_local" || - agent.adapterType === "cursor"; - - const updateAgent = useMutation({ - mutationFn: (data: Record) => agentsApi.update(agent.id, data, companyId), - onMutate: () => setAwaitingRefresh(true), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: queryKeys.agents.detail(agent.id) }); - queryClient.invalidateQueries({ queryKey: queryKeys.agents.detail(agent.urlKey) }); - }, - onError: () => setAwaitingRefresh(false), - }); - - const uploadMarkdownImage = useMutation({ - mutationFn: async ({ file, namespace }: { file: File; namespace: string }) => { - if (!selectedCompanyId) throw new Error("Select a company to upload images"); - return assetsApi.uploadImage(selectedCompanyId, file, namespace); - }, - }); - - useEffect(() => { - if (awaitingRefresh && agent !== lastAgentRef.current) { - setAwaitingRefresh(false); - setDraft(null); - } - lastAgentRef.current = agent; - }, [agent, awaitingRefresh]); - - const isSaving = updateAgent.isPending || awaitingRefresh; - - useEffect(() => { onSavingChange(isSaving); }, [onSavingChange, isSaving]); - useEffect(() => { onDirtyChange(isDirty); }, [onDirtyChange, isDirty]); - - useEffect(() => { - onSaveActionChange(isDirty ? () => { - updateAgent.mutate({ adapterConfig: { promptTemplate: draft } }); - } : null); - }, [onSaveActionChange, isDirty, draft, updateAgent]); - - useEffect(() => { - onCancelActionChange(isDirty ? () => setDraft(null) : null); - }, [onCancelActionChange, isDirty]); - - if (!isLocal) { - return ( -
-

- Prompt templates are only available for local adapters. -

-
- ); - } - - return ( -
-
-

Prompt Template

-
-

- {help.promptTemplate} -

- setDraft(v ?? "")} - placeholder="You are agent {{ agent.name }}. Your role is {{ agent.role }}..." - contentClassName="min-h-[88px] text-sm font-mono" - imageUploadHandler={async (file) => { - const namespace = `agents/${agent.id}/prompt-template`; - const asset = await uploadMarkdownImage.mutateAsync({ file, namespace }); - return asset.contentPath; - }} - /> -
- Prompt template is replayed on every heartbeat. Keep it compact and dynamic to avoid recurring token cost and cache churn. -
-
-
-
- ); -} - function SkillsTab({ agent }: { agent: Agent }) { const instructionsPath = typeof agent.adapterConfig?.instructionsFilePath === "string" && agent.adapterConfig.instructionsFilePath.trim().length > 0