From dac36398d94dc283a464dd17cccb19b13df33acf Mon Sep 17 00:00:00 2001 From: hugocasa Date: Mon, 12 Oct 2026 14:22:16 +0200 Subject: [PATCH] feat: open an agent's version history from its menu Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Vo7HXMdgqXJhR7p8YyVgjB --- .../components/common/table/AgentRow.svelte | 10 ++++++ .../lib/components/flows/AgentHistory.svelte | 34 +++++++++++++++++++ .../src/lib/components/flows/agentActions.ts | 6 +++- .../agents/get/[...path]/+page.svelte | 4 +++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 frontend/src/lib/components/flows/AgentHistory.svelte diff --git a/frontend/src/lib/components/common/table/AgentRow.svelte b/frontend/src/lib/components/common/table/AgentRow.svelte index 71228b66e4..013bd334d9 100644 --- a/frontend/src/lib/components/common/table/AgentRow.svelte +++ b/frontend/src/lib/components/common/table/AgentRow.svelte @@ -14,6 +14,7 @@ import ChatFlowBadge from '$lib/components/flows/ChatFlowBadge.svelte' import { keepsManagedMemory } from '$lib/components/flows/agentFormFields' import { agentMenuItems, deleteAgent } from '$lib/components/flows/agentActions' + import AgentHistory from '$lib/components/flows/AgentHistory.svelte' import { getDeployUiSettings } from '$lib/components/home/deploy_ui' import Row from './Row.svelte' import { selectMenuItems, type RowSelection } from './rowSelection' @@ -55,8 +56,16 @@ let editHref = $derived(`${base}/agents/edit/${agent.path}`) // A draft-only agent has nothing deployed for its page to run, so it opens in the editor. let rowHref = $derived(agent.draft_only ? editHref : `${base}/agents/get/${agent.path}`) + let history: AgentHistory | undefined = $state(undefined) + dispatch('change')} +/> + {#snippet chatBadge()} {/snippet} @@ -114,6 +123,7 @@ operator: $userStore?.operator, onPermissions: () => shareModal.openDrawer?.(agent.path, 'resource'), onDeploy: () => deploymentDrawer.openDrawer(agent.path, 'resource'), + onHistory: () => history?.open(), onDelete: (event) => { const { path } = agent if (event?.shiftKey) remove(path) diff --git a/frontend/src/lib/components/flows/AgentHistory.svelte b/frontend/src/lib/components/flows/AgentHistory.svelte new file mode 100644 index 0000000000..c6deff1e59 --- /dev/null +++ b/frontend/src/lib/components/flows/AgentHistory.svelte @@ -0,0 +1,34 @@ + + + + drawer?.closeDrawer()} noPadding> + { + drawer?.closeDrawer() + // A restore writes the resource as a deploy does, so whatever shows this agent re-reads it. + markAgentWritten($workspaceStore ?? undefined, path) + onRestored?.() + }} + /> + + diff --git a/frontend/src/lib/components/flows/agentActions.ts b/frontend/src/lib/components/flows/agentActions.ts index 1cf2615981..f99701296a 100644 --- a/frontend/src/lib/components/flows/agentActions.ts +++ b/frontend/src/lib/components/flows/agentActions.ts @@ -1,4 +1,4 @@ -import { Copy, Eye, FileUp, List, Shield, Trash } from 'lucide-svelte' +import { Copy, Eye, FileUp, History, List, Shield, Trash } from 'lucide-svelte' import { ResourceService } from '$lib/gen' import { sendUserToast } from '$lib/toast' import { copyToClipboard, type Item } from '$lib/utils' @@ -32,6 +32,7 @@ export function agentMenuItems(agent: { deployUiSettings: WorkspaceDeployUISettings | undefined onPermissions: () => void onDeploy: () => void + onHistory: () => void onDelete: (event?: MouseEvent) => void }): Item[] { const deployable = @@ -70,6 +71,9 @@ export function agentMenuItems(agent: { ...(deployable ? [{ displayName: 'Deploy to prod/staging', icon: FileUp, action: agent.onDeploy }] : []), + ...(agent.draftOnly || agent.operator + ? [] + : [{ displayName: 'Version history', icon: History, action: agent.onHistory }]), { displayName: 'Delete', icon: Trash, diff --git a/frontend/src/routes/(root)/(logged)/agents/get/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/agents/get/[...path]/+page.svelte index 3070345ddf..a95cd50a83 100644 --- a/frontend/src/routes/(root)/(logged)/agents/get/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/agents/get/[...path]/+page.svelte @@ -18,6 +18,7 @@ import { Alert } from '$lib/components/common' import { keepsManagedMemory } from '$lib/components/flows/agentFormFields' import { agentMenuItems, deleteAgent } from '$lib/components/flows/agentActions' + import AgentHistory from '$lib/components/flows/AgentHistory.svelte' import { getDeployUiSettings } from '$lib/components/home/deploy_ui' import { userStore, workspaceStore } from '$lib/stores' import { sendUserToast } from '$lib/toast' @@ -41,6 +42,7 @@ let configModal: AgentConfigModal | undefined = $state(undefined) let shareModal: ShareModal | undefined = $state(undefined) let deploymentDrawer: DeployWorkspaceDrawer | undefined = $state(undefined) + let history: AgentHistory | undefined = $state(undefined) let deleteOpen = $state(false) let evalsModal: AgentEvalsModal | undefined = $state(undefined) let runForm: RunForm | undefined = $state(undefined) @@ -78,6 +80,7 @@ deployUiSettings: deployUiSettings.current, onPermissions: () => shareModal?.openDrawer?.(path, 'resource'), onDeploy: () => deploymentDrawer?.openDrawer(path, 'resource'), + onHistory: () => history?.open(), onDelete: () => (deleteOpen = true) }).map((item) => ({ label: item.displayName, @@ -92,6 +95,7 @@ + reloaded++} />