Skip to content

Commit 420a8a7

Browse files
NickB03claude
andcommitted
fix(tool-ui): suffix agent-artifact downloads with version label
For multi-version artifacts, the download filename was memoized on title + artifactType + language only, so each version saved with the same name and silently overwrote prior downloads. Suffix the slug with the active version label when more than one version exists; single-version artifacts keep their existing filename. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a5896b6 commit 420a8a7

2 files changed

Lines changed: 19 additions & 9 deletions

File tree

components/tool-ui/agent-artifact/agent-artifact.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ describe('AgentArtifact', () => {
6161
expect(screen.getByText('120 tokens')).toBeInTheDocument()
6262
expect(
6363
screen.getByRole('link', { name: 'Download artifact content' })
64-
).toHaveAttribute('download', 'component-spec.md')
64+
).toHaveAttribute('download', 'component-spec-version-2.md')
6565
})
6666

6767
it('handles denied clipboard writes without surfacing an unhandled rejection', async () => {

components/tool-ui/agent-artifact/agent-artifact.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,22 @@ function parseTable(content: string) {
114114
return parseMarkdownTable(content) ?? parseCsvTable(content)
115115
}
116116

117+
function slugify(value: string) {
118+
return value
119+
.toLowerCase()
120+
.replace(/[^a-z0-9]+/g, '-')
121+
.replace(/^-|-$/g, '')
122+
}
123+
117124
function getDownloadFilename(
118125
title: string,
119126
artifactType: string,
120-
language?: string
127+
language?: string,
128+
versionLabel?: string
121129
) {
122-
const slug = title
123-
.toLowerCase()
124-
.replace(/[^a-z0-9]+/g, '-')
125-
.replace(/^-|-$/g, '')
130+
const titleSlug = slugify(title) || 'artifact'
131+
const versionSlug = versionLabel ? slugify(versionLabel) : ''
132+
const slug = versionSlug ? `${titleSlug}-${versionSlug}` : titleSlug
126133
const extension =
127134
artifactType === 'table'
128135
? 'csv'
@@ -132,7 +139,7 @@ function getDownloadFilename(
132139
? 'ts'
133140
: 'txt'
134141

135-
return `${slug || 'artifact'}.${extension}`
142+
return `${slug}.${extension}`
136143
}
137144

138145
export function AgentArtifact({
@@ -174,9 +181,12 @@ export function AgentArtifact({
174181
() => `data:text/plain;charset=utf-8,${encodeURIComponent(activeContent)}`,
175182
[activeContent]
176183
)
184+
const downloadVersionLabel =
185+
versions && versions.length > 1 ? activeVersion?.label : undefined
177186
const downloadFilename = useMemo(
178-
() => getDownloadFilename(title, artifactType, language),
179-
[artifactType, language, title]
187+
() =>
188+
getDownloadFilename(title, artifactType, language, downloadVersionLabel),
189+
[artifactType, downloadVersionLabel, language, title]
180190
)
181191
const Icon = artifactIcons[artifactType]
182192

0 commit comments

Comments
 (0)