Chat converts a database.Chat to a codersdk.Chat. It coalesces nil slices and maps to empty values for JSON serialization and derives RootChatID from the parent chain when not explicitly set. When diffStatus is non-nil the response includes diff metadata. When files is non-empty the response include
(c database.Chat, diffStatus *database.ChatDiffStatus, files []database.GetChatFileMetadataByChatIDRow)
| 1733 | // When files is non-empty the response includes file metadata; |
| 1734 | // pass nil to omit the files field (e.g. list endpoints). |
| 1735 | func Chat(c database.Chat, diffStatus *database.ChatDiffStatus, files []database.GetChatFileMetadataByChatIDRow) codersdk.Chat { |
| 1736 | mcpServerIDs := c.MCPServerIDs |
| 1737 | if mcpServerIDs == nil { |
| 1738 | mcpServerIDs = []uuid.UUID{} |
| 1739 | } |
| 1740 | labels := map[string]string(c.Labels) |
| 1741 | if labels == nil { |
| 1742 | labels = map[string]string{} |
| 1743 | } |
| 1744 | lastError := decodeChatLastError(c.LastError) |
| 1745 | chat := codersdk.Chat{ |
| 1746 | ID: c.ID, |
| 1747 | OrganizationID: c.OrganizationID, |
| 1748 | OwnerID: c.OwnerID, |
| 1749 | OwnerUsername: c.OwnerUsername, |
| 1750 | OwnerName: c.OwnerName, |
| 1751 | LastModelConfigID: c.LastModelConfigID, |
| 1752 | Title: c.Title, |
| 1753 | Status: codersdk.ChatStatus(c.Status), |
| 1754 | Archived: c.Archived, |
| 1755 | PinOrder: c.PinOrder, |
| 1756 | CreatedAt: c.CreatedAt, |
| 1757 | UpdatedAt: c.UpdatedAt, |
| 1758 | MCPServerIDs: mcpServerIDs, |
| 1759 | Labels: labels, |
| 1760 | ClientType: codersdk.ChatClientType(c.ClientType), |
| 1761 | LastError: lastError, |
| 1762 | } |
| 1763 | if c.LastTurnSummary.Valid { |
| 1764 | chat.LastTurnSummary = &c.LastTurnSummary.String |
| 1765 | } |
| 1766 | if c.PlanMode.Valid { |
| 1767 | chat.PlanMode = codersdk.ChatPlanMode(c.PlanMode.ChatPlanMode) |
| 1768 | } |
| 1769 | if c.ParentChatID.Valid { |
| 1770 | parentChatID := c.ParentChatID.UUID |
| 1771 | chat.ParentChatID = &parentChatID |
| 1772 | } |
| 1773 | // Always initialize Children to an empty slice so the JSON |
| 1774 | // field serializes as [] rather than null. Root chats may |
| 1775 | // later have children populated; child chats remain empty |
| 1776 | // because nesting depth is capped at 1. |
| 1777 | chat.Children = []codersdk.Chat{} |
| 1778 | switch { |
| 1779 | case c.RootChatID.Valid: |
| 1780 | rootChatID := c.RootChatID.UUID |
| 1781 | chat.RootChatID = &rootChatID |
| 1782 | case c.ParentChatID.Valid: |
| 1783 | rootChatID := c.ParentChatID.UUID |
| 1784 | chat.RootChatID = &rootChatID |
| 1785 | default: |
| 1786 | rootChatID := c.ID |
| 1787 | chat.RootChatID = &rootChatID |
| 1788 | } |
| 1789 | if c.WorkspaceID.Valid { |
| 1790 | chat.WorkspaceID = &c.WorkspaceID.UUID |
| 1791 | } |
| 1792 | if c.BuildID.Valid { |