Skip to content

Commit 3f33d3e

Browse files
committed
fix: added ContentType as a string alias in types.go
Signed-off-by: Sanskarzz <sanskar.gur@gmail.com>
1 parent 963b417 commit 3f33d3e

File tree

9 files changed

+93
-86
lines changed

9 files changed

+93
-86
lines changed

pkg/vmcp/client/meta_integration_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func TestMetaPreservation_CallTool(t *testing.T) {
6969
// Verify content is also correct
7070
assert.NotNil(t, result.Content)
7171
assert.Len(t, result.Content, 1)
72-
assert.Equal(t, "text", result.Content[0].Type)
72+
assert.Equal(t, vmcp.ContentTypeText, result.Content[0].Type)
7373
assert.Equal(t, "Response from test tool", result.Content[0].Text)
7474
}
7575

@@ -111,7 +111,7 @@ func TestMetaPreservation_CallTool_NoMeta(t *testing.T) {
111111
// Verify content is still correct
112112
assert.NotNil(t, result.Content)
113113
assert.Len(t, result.Content, 1)
114-
assert.Equal(t, "text", result.Content[0].Type)
114+
assert.Equal(t, vmcp.ContentTypeText, result.Content[0].Type)
115115
}
116116

117117
// TestMetaPreservation_CallTool_Error tests that _meta fields are preserved even when tool returns IsError=true.

pkg/vmcp/composer/workflow_engine_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ func TestWorkflowEngine_ExecuteWorkflow_IsErrorHandling(t *testing.T) {
137137
Return(&vmcp.ToolCallResult{
138138
IsError: true,
139139
Content: []vmcp.Content{{
140-
Type: "text",
140+
Type: vmcp.ContentTypeText,
141141
Text: "Tool execution failed: invalid input",
142142
}},
143143
}, nil),
144144
te.Backend.EXPECT().CallTool(gomock.Any(), target, "test.tool", gomock.Any(), gomock.Any()).
145145
Return(&vmcp.ToolCallResult{
146146
IsError: true,
147147
Content: []vmcp.Content{{
148-
Type: "text",
148+
Type: vmcp.ContentTypeText,
149149
Text: "Tool execution failed: temporary error",
150150
}},
151151
}, nil),
@@ -190,7 +190,7 @@ func TestWorkflowEngine_ExecuteWorkflow_IsErrorExhaustsRetries(t *testing.T) {
190190
Return(&vmcp.ToolCallResult{
191191
IsError: true,
192192
Content: []vmcp.Content{{
193-
Type: "text",
193+
Type: vmcp.ContentTypeText,
194194
Text: "Persistent error: operation failed",
195195
}},
196196
}, nil).Times(3) // Initial + 2 retries

pkg/vmcp/conversion/content.go

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,31 @@ import (
1717
"github.com/stacklok/toolhive/pkg/vmcp"
1818
)
1919

20-
const (
21-
contentTypeText = "text"
22-
contentTypeImage = "image"
23-
contentTypeAudio = "audio"
24-
contentTypeResource = "resource"
25-
contentTypeLink = "resource_link"
26-
)
27-
2820
// ConvertMCPContent converts a single mcp.Content item to vmcp.Content.
2921
// Unknown content types are returned as vmcp.Content{Type: "unknown"}.
3022
func ConvertMCPContent(content mcp.Content) vmcp.Content {
3123
if text, ok := mcp.AsTextContent(content); ok {
32-
return vmcp.Content{Type: contentTypeText, Text: text.Text}
24+
return vmcp.Content{Type: vmcp.ContentTypeText, Text: text.Text}
3325
}
3426
if img, ok := mcp.AsImageContent(content); ok {
35-
return vmcp.Content{Type: contentTypeImage, Data: img.Data, MimeType: img.MIMEType}
27+
return vmcp.Content{Type: vmcp.ContentTypeImage, Data: img.Data, MimeType: img.MIMEType}
3628
}
3729
if audio, ok := mcp.AsAudioContent(content); ok {
38-
return vmcp.Content{Type: contentTypeAudio, Data: audio.Data, MimeType: audio.MIMEType}
30+
return vmcp.Content{Type: vmcp.ContentTypeAudio, Data: audio.Data, MimeType: audio.MIMEType}
3931
}
4032
if res, ok := mcp.AsEmbeddedResource(content); ok {
4133
if textRes, ok := mcp.AsTextResourceContents(res.Resource); ok {
42-
return vmcp.Content{Type: "resource", Text: textRes.Text, URI: textRes.URI, MimeType: textRes.MIMEType}
34+
return vmcp.Content{Type: vmcp.ContentTypeResource, Text: textRes.Text, URI: textRes.URI, MimeType: textRes.MIMEType}
4335
}
4436
if blobRes, ok := mcp.AsBlobResourceContents(res.Resource); ok {
45-
return vmcp.Content{Type: "resource", Data: blobRes.Blob, URI: blobRes.URI, MimeType: blobRes.MIMEType}
37+
return vmcp.Content{Type: vmcp.ContentTypeResource, Data: blobRes.Blob, URI: blobRes.URI, MimeType: blobRes.MIMEType}
4638
}
4739
slog.Debug("Embedded resource has unknown resource contents type", "type", fmt.Sprintf("%T", res.Resource))
48-
return vmcp.Content{Type: "resource"}
40+
return vmcp.Content{Type: vmcp.ContentTypeResource}
4941
}
5042
if link, ok := content.(mcp.ResourceLink); ok {
5143
return vmcp.Content{
52-
Type: contentTypeLink,
44+
Type: vmcp.ContentTypeLink,
5345
URI: link.URI,
5446
Name: link.Name,
5547
Description: link.Description,
@@ -74,13 +66,13 @@ func ConvertMCPContents(contents []mcp.Content) []vmcp.Content {
7466
// Unknown content types are converted to empty text with a warning.
7567
func ToMCPContent(content vmcp.Content) mcp.Content {
7668
switch content.Type {
77-
case contentTypeText:
69+
case vmcp.ContentTypeText:
7870
return mcp.NewTextContent(content.Text)
79-
case contentTypeImage:
71+
case vmcp.ContentTypeImage:
8072
return mcp.NewImageContent(content.Data, content.MimeType)
81-
case contentTypeAudio:
73+
case vmcp.ContentTypeAudio:
8274
return mcp.NewAudioContent(content.Data, content.MimeType)
83-
case contentTypeResource:
75+
case vmcp.ContentTypeResource:
8476
// Reconstruct embedded resource from vmcp.Content fields.
8577
// Text content takes precedence over blob content when both are present.
8678
if content.Text != "" {
@@ -104,7 +96,7 @@ func ToMCPContent(content vmcp.Content) mcp.Content {
10496
MIMEType: content.MimeType,
10597
Text: "",
10698
})
107-
case contentTypeLink:
99+
case vmcp.ContentTypeLink:
108100
// Reconstruct a ResourceLink from vmcp.Content fields.
109101
return mcp.NewResourceLink(content.URI, content.Name, content.Description, content.MimeType)
110102
default:
@@ -222,15 +214,15 @@ func ContentArrayToMap(content []vmcp.Content) map[string]any {
222214

223215
for _, item := range content {
224216
switch item.Type {
225-
case contentTypeText:
226-
key := contentTypeText
217+
case vmcp.ContentTypeText:
218+
key := string(vmcp.ContentTypeText)
227219
if textIndex > 0 {
228220
key = fmt.Sprintf("text_%d", textIndex)
229221
}
230222
result[key] = item.Text
231223
textIndex++
232224

233-
case contentTypeImage:
225+
case vmcp.ContentTypeImage:
234226
key := fmt.Sprintf("image_%d", imageIndex)
235227
result[key] = item.Data
236228
imageIndex++

0 commit comments

Comments
 (0)