Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions coderd/x/chatd/chatprompt/chatprompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -1588,6 +1588,7 @@ func partsToMessageParts(
continue
}
result = append(result, fantasy.FilePart{
Filename: name,
Data: data,
MediaType: mediaType,
ProviderOptions: opts,
Expand Down
1 change: 1 addition & 0 deletions coderd/x/chatd/chatprompt/chatprompt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ func TestConvertMessagesWithFiles_MixedResolvedAndMissingFilePartsInSingleMessag

filePart, ok := fantasy.AsMessagePart[fantasy.FilePart](prompt[0].Content[0])
require.True(t, ok, "expected first part to stay a FilePart")
require.Equal(t, "resolved.png", filePart.Filename)
require.Equal(t, resolvedData, filePart.Data)
require.Equal(t, "image/png", filePart.MediaType)

Expand Down
21 changes: 16 additions & 5 deletions coderd/x/chatd/chatprovider/chatprovider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1308,10 +1308,11 @@ func TestModelFromConfig_ExtraHeaders(t *testing.T) {
// path that lets a user-uploaded PDF actually reach Claude/Bedrock: a
// fantasy.FilePart with MediaType "application/pdf" must be serialized as an
// Anthropic "document" content block with a base64 source carrying the PDF
// bytes. Older fantasy versions silently dropped PDF FileParts in the
// Anthropic provider, so the user message ended up empty and the model never
// saw the document. See coder/fantasy#37 (cherry-pick of upstream
// charmbracelet/fantasy#197). The Generate call would fail outright on the
// bytes and a sanitized filename as the document title. Older fantasy versions
// silently dropped PDF FileParts in the Anthropic provider, so the user
// message ended up empty and the model never saw the document. The underlying
// PDF block support came from coder/fantasy#37, a cherry-pick of upstream
// charmbracelet/fantasy#197. The Generate call would fail outright on the
// regressed code path because the dropped FilePart leaves the request with
// zero messages.
func TestModelFromConfig_AnthropicPDFFilePartReachesProvider(t *testing.T) {
Expand All @@ -1330,6 +1331,7 @@ func TestModelFromConfig_AnthropicPDFFilePartReachesProvider(t *testing.T) {

var blocks []struct {
Type string `json:"type"`
Title string `json:"title"`
Source struct {
Type string `json:"type"`
MediaType string `json:"media_type"`
Expand All @@ -1346,6 +1348,11 @@ func TestModelFromConfig_AnthropicPDFFilePartReachesProvider(t *testing.T) {
}
assert.Equal(t, "base64", block.Source.Type, "PDF document block must use a base64 source")
assert.Equal(t, wantData, block.Source.Data, "PDF bytes must round-trip base64 unchanged")
assert.Equal(t,
"quarterly report v1 pdf",
block.Title,
"PDF filename must reach Anthropic as a sanitized document title",
)
if block.Source.MediaType != "" {
assert.Equal(t, "application/pdf", block.Source.MediaType)
}
Expand All @@ -1369,7 +1376,11 @@ func TestModelFromConfig_AnthropicPDFFilePartReachesProvider(t *testing.T) {
{
Role: fantasy.MessageRoleUser,
Content: []fantasy.MessagePart{
fantasy.FilePart{Data: pdfData, MediaType: "application/pdf"},
fantasy.FilePart{
Filename: "quarterly_report.v1.pdf",
Data: pdfData,
MediaType: "application/pdf",
},
},
},
},
Expand Down
8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ replace github.com/spf13/afero => github.com/aslilac/afero v0.0.0-20250403163713
// emit a Base64 PDF document block for application/pdf FileParts on the
// Anthropic provider so user-uploaded PDFs actually reach Claude/Bedrock
// instead of being silently dropped.
// See: https://github.com/coder/fantasy/commits/7d46e640327a
replace charm.land/fantasy => github.com/coder/fantasy v0.0.0-20260602023814-7d46e640327a
// 11) coder/fantasy#38 @b2b2fc6d524c, forward PDF and text filenames as
// a sanitized Anthropic document title so Claude can refer to
// attachments by name, and warn on unsupported FilePart media types
// instead of silently dropping them.
// See: https://github.com/coder/fantasy/commits/b2b2fc6d524c
replace charm.land/fantasy => github.com/coder/fantasy v0.0.0-20260604065934-b2b2fc6d524c

// coder/coder uses a fork of charmbracelet's fork of the Anthropic Go SDK
// with performance improvements and Bedrock header cleanup.
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,8 @@ github.com/coder/bubbletea v1.2.2-0.20241212190825-007a1cdb2c41 h1:SBN/DA63+ZHwu
github.com/coder/bubbletea v1.2.2-0.20241212190825-007a1cdb2c41/go.mod h1:I9ULxr64UaOSUv7hcb3nX4kowodJCVS7vt7VVJk/kW4=
github.com/coder/clistat v1.2.1 h1:P9/10njXMyj5cWzIU5wkRsSy5LVQH49+tcGMsAgWX0w=
github.com/coder/clistat v1.2.1/go.mod h1:m7SC0uj88eEERgvF8Kn6+w6XF21BeSr+15f7GoLAw0A=
github.com/coder/fantasy v0.0.0-20260602023814-7d46e640327a h1:ffQixHAwjJLHgFfe4rtrAsFNRGhEyWnBSpInnLIxDPo=
github.com/coder/fantasy v0.0.0-20260602023814-7d46e640327a/go.mod h1:wZ0e3lEPqrM0XiIdAUQLvMKCLYhc3gi96MRX2wjbX44=
github.com/coder/fantasy v0.0.0-20260604065934-b2b2fc6d524c h1:POkVNoDnbNv3CfeFInwai0yMkjGkdqjgqIcG/SlnuLg=
github.com/coder/fantasy v0.0.0-20260604065934-b2b2fc6d524c/go.mod h1:wZ0e3lEPqrM0XiIdAUQLvMKCLYhc3gi96MRX2wjbX44=
github.com/coder/flog v1.1.0 h1:kbAes1ai8fIS5OeV+QAnKBQE22ty1jRF/mcAwHpLBa4=
github.com/coder/flog v1.1.0/go.mod h1:UQlQvrkJBvnRGo69Le8E24Tcl5SJleAAR7gYEHzAmdQ=
github.com/coder/go-httpstat v0.0.0-20230801153223-321c88088322 h1:m0lPZjlQ7vdVpRBPKfYIFlmgevoTkBxB10wv6l2gOaU=
Expand Down
Loading