MCPcopy Create free account
hub / github.com/coder/coder / partsToMessageParts

Function partsToMessageParts

coderd/x/chatd/chatprompt/chatprompt.go:1499–1632  ·  view source on GitHub ↗

partsToMessageParts converts SDK chat message parts into fantasy message parts for LLM dispatch. resolved is a lookup map for file bytes, and policy controls whether missing file-backed parts are dropped or replaced with text placeholders.

(
	ctx context.Context,
	logger slog.Logger,
	parts []codersdk.ChatMessagePart,
	resolved map[uuid.UUID]FileData,
	policy missingFilePolicy,
)

Source from the content-addressed store, hash-verified

1497// bytes, and policy controls whether missing file-backed parts are
1498// dropped or replaced with text placeholders.
1499func partsToMessageParts(
1500 ctx context.Context,
1501 logger slog.Logger,
1502 parts []codersdk.ChatMessagePart,
1503 resolved map[uuid.UUID]FileData,
1504 policy missingFilePolicy,
1505) []fantasy.MessagePart {
1506 result := make([]fantasy.MessagePart, 0, len(parts))
1507 for _, part := range parts {
1508 switch part.Type {
1509 case codersdk.ChatMessagePartTypeText:
1510 // Anthropic rejects empty text content blocks with
1511 // "text content blocks must be non-empty". Empty parts
1512 // can arise when a stream sends TextStart/TextEnd with
1513 // no delta in between. We filter them here rather than
1514 // at persistence time to preserve the raw record.
1515 if strings.TrimSpace(part.Text) == "" {
1516 continue
1517 }
1518 result = append(result, fantasy.TextPart{
1519 Text: part.Text,
1520 ProviderOptions: providerMetadataToOptions(logger, part.ProviderMetadata),
1521 })
1522 case codersdk.ChatMessagePartTypeReasoning:
1523 opts := providerMetadataToOptions(logger, part.ProviderMetadata)
1524 if strings.TrimSpace(part.Text) == "" && !chatsanitize.HasAnthropicSignedReasoningOptions(opts) {
1525 continue
1526 }
1527 result = append(result, fantasy.ReasoningPart{
1528 Text: part.Text,
1529 ProviderOptions: opts,
1530 })
1531 case codersdk.ChatMessagePartTypeToolCall:
1532 result = append(result, fantasy.ToolCallPart{
1533 ToolCallID: sanitizeToolCallID(part.ToolCallID),
1534 ToolName: part.ToolName,
1535 Input: string(part.Args),
1536 ProviderExecuted: part.ProviderExecuted,
1537 ProviderOptions: providerMetadataToOptions(logger, part.ProviderMetadata),
1538 })
1539 case codersdk.ChatMessagePartTypeToolResult:
1540 result = append(result, toolResultPartToMessagePart(logger, part))
1541 case codersdk.ChatMessagePartTypeFile:
1542 data := part.Data
1543 mediaType := part.MediaType
1544 var name string
1545 resolvedFile := false
1546 if part.FileID.Valid {
1547 if fd, ok := resolved[part.FileID.UUID]; ok {
1548 resolvedFile = true
1549 data = fd.Data
1550 name = fd.Name
1551 if mediaType == "" {
1552 mediaType = fd.MediaType
1553 }
1554 }
1555 }
1556 opts := providerMetadataToOptions(logger, part.ProviderMetadata)

Callers 1

ConvertMessagesWithFilesFunction · 0.85

Calls 11

sanitizeToolCallIDFunction · 0.85
isSyntheticPasteFunction · 0.85
formatSyntheticPasteTextFunction · 0.85
fileReferencePartToTextFunction · 0.85
WriteStringMethod · 0.80
InfoMethod · 0.45
StringMethod · 0.45

Tested by

no test coverage detected