MCPcopy Index your code
hub / github.com/coder/coder / toolResultContentToPart

Function toolResultContentToPart

coderd/x/chatd/chatprompt/chatprompt.go:853–928  ·  view source on GitHub ↗

toolResultContentToPart converts a fantasy ToolResultContent into a ChatMessagePart.

(
	logger slog.Logger,
	content fantasy.ToolResultContent,
	logMalformedAttachmentMetadata func(fantasy.ToolResultContent, error),
)

Source from the content-addressed store, hash-verified

851// toolResultContentToPart converts a fantasy ToolResultContent into a
852// ChatMessagePart.
853func toolResultContentToPart(
854 logger slog.Logger,
855 content fantasy.ToolResultContent,
856 logMalformedAttachmentMetadata func(fantasy.ToolResultContent, error),
857) codersdk.ChatMessagePart {
858 var result json.RawMessage
859 var isError bool
860 var isMedia bool
861
862 switch output := content.Result.(type) {
863 case fantasy.ToolResultOutputContentError:
864 isError = true
865 if output.Error != nil {
866 raw := json.RawMessage(strings.TrimSpace(output.Error.Error()))
867 if isSubagentLifecycleToolName(content.ToolName) && hasErrorField(raw) {
868 result = raw
869 } else {
870 var marshalErr error
871 result, marshalErr = json.Marshal(map[string]any{"error": output.Error.Error()})
872 if marshalErr != nil {
873 logger.Error(context.Background(), "failed to marshal error tool result",
874 slog.F("tool_name", content.ToolName),
875 slog.F("tool_call_id", content.ToolCallID),
876 slog.Error(marshalErr),
877 )
878 result = []byte(`{"error":"marshal failure"}`)
879 }
880 }
881 } else {
882 result = []byte(`{"error":""}`)
883 }
884 case fantasy.ToolResultOutputContentText:
885 sanitized := strings.ToValidUTF8(output.Text, "\uFFFD")
886 result = json.RawMessage(sanitized)
887 // Ensure valid JSON; wrap in an object if not.
888 if !json.Valid(result) {
889 var marshalErr error
890 result, marshalErr = json.Marshal(map[string]any{"output": sanitized})
891 if marshalErr != nil {
892 logger.Error(context.Background(), "failed to marshal text tool result",
893 slog.F("tool_name", content.ToolName),
894 slog.F("tool_call_id", content.ToolCallID),
895 slog.Error(marshalErr),
896 )
897 result = []byte(`{}`)
898 }
899 }
900 case fantasy.ToolResultOutputContentMedia:
901 isMedia = true
902 persisted := persistedMediaResult{
903 Data: output.Data,
904 MimeType: output.MediaType,
905 Text: strings.ToValidUTF8(output.Text, "\uFFFD"),
906 }
907 // Tool renderers only receive the persisted result JSON, while
908 // ClientMetadata is consumed later to append sibling file parts.
909 // Mirror attachment identity here so promoted media can be
910 // recognized as the same durable attachment downstream.

Callers 2

sdkPartFromContentFunction · 0.70
export_test.goFile · 0.70

Calls 9

hasErrorFieldFunction · 0.85
ToolResultToPartFunction · 0.85
marshalProviderMetadataFunction · 0.85
ValidMethod · 0.65
ErrorMethod · 0.45
MarshalMethod · 0.45
StringMethod · 0.45

Tested by

no test coverage detected