feat: open an agent's version history from its menu

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vo7HXMdgqXJhR7p8YyVgjB
This commit is contained in:
hugocasa
2026-10-12 14:22:16 +02:00
co-authored by Claude Opus 5.5
parent 3cfc606982
commit dac36398d9
4 changed files with 53 additions and 1 deletions
@@ -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)
</script>
<AgentHistory
bind:this={history}
path={agent.path}
canRestore={agent.canWrite}
onRestored={() => dispatch('change')}
/>
{#snippet chatBadge()}
<ChatFlowBadge title="Managed memory on: this agent opens as a conversation" />
{/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)
@@ -0,0 +1,34 @@
<script lang="ts">
import { Drawer, DrawerContent } from '$lib/components/common'
import ResourceVersionHistory from '$lib/components/ResourceVersionHistory.svelte'
import { workspaceStore } from '$lib/stores'
import { markAgentWritten } from './agentEditorStore.svelte'
interface Props {
path: string
canRestore: boolean
onRestored?: () => void
}
let { path, canRestore, onRestored }: Props = $props()
let drawer: Drawer | undefined = $state()
export function open() {
drawer?.openDrawer()
}
</script>
<Drawer bind:this={drawer} size="1200px">
<DrawerContent title="Version history" on:close={() => drawer?.closeDrawer()} noPadding>
<ResourceVersionHistory
{path}
{canRestore}
onRestore={() => {
drawer?.closeDrawer()
// A restore writes the resource as a deploy does, so whatever shows this agent re-reads it.
markAgentWritten($workspaceStore ?? undefined, path)
onRestored?.()
}}
/>
</DrawerContent>
</Drawer>
@@ -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,
@@ -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 @@
<ShareModal bind:this={shareModal} />
<DeployWorkspaceDrawer bind:this={deploymentDrawer} />
<AgentHistory bind:this={history} {path} canRestore={canEdit} onRestored={() => reloaded++} />
<ConfirmationModal
open={deleteOpen}
title="Delete agent"