copyParentContextMessages reads persisted context-file and skill messages from the parent chat and inserts copies into the child chat. This ensures sub-agents inherit the same instruction and skill context as their parent without independently re-fetching from the agent.
( ctx context.Context, logger slog.Logger, store database.Store, parent database.Chat, child database.Chat, )
| 1123 | // skill context as their parent without independently re-fetching |
| 1124 | // from the agent. |
| 1125 | func copyParentContextMessages( |
| 1126 | ctx context.Context, |
| 1127 | logger slog.Logger, |
| 1128 | store database.Store, |
| 1129 | parent database.Chat, |
| 1130 | child database.Chat, |
| 1131 | ) ([]codersdk.ChatMessagePart, error) { |
| 1132 | parentMessages, err := store.GetChatMessagesByChatID(ctx, database.GetChatMessagesByChatIDParams{ |
| 1133 | ChatID: parent.ID, |
| 1134 | AfterID: 0, |
| 1135 | }) |
| 1136 | if err != nil { |
| 1137 | return nil, xerrors.Errorf("get parent messages: %w", err) |
| 1138 | } |
| 1139 | |
| 1140 | var ( |
| 1141 | copiedParts []codersdk.ChatMessagePart |
| 1142 | copiedRole database.ChatMessageRole |
| 1143 | copiedVisibility database.ChatMessageVisibility |
| 1144 | copiedVersion int16 |
| 1145 | ) |
| 1146 | for _, msg := range parentMessages { |
| 1147 | if !msg.Content.Valid { |
| 1148 | continue |
| 1149 | } |
| 1150 | var parts []codersdk.ChatMessagePart |
| 1151 | if err := json.Unmarshal(msg.Content.RawMessage, &parts); err != nil { |
| 1152 | logger.Warn(ctx, "failed to unmarshal parent context message", |
| 1153 | slog.F("parent_chat_id", parent.ID), |
| 1154 | slog.F("message_id", msg.ID), |
| 1155 | slog.Error(err), |
| 1156 | ) |
| 1157 | continue |
| 1158 | } |
| 1159 | |
| 1160 | messageContextParts := FilterContextParts(parts, true) |
| 1161 | if len(messageContextParts) == 0 { |
| 1162 | continue |
| 1163 | } |
| 1164 | if copiedParts == nil { |
| 1165 | copiedRole = msg.Role |
| 1166 | copiedVisibility = msg.Visibility |
| 1167 | copiedVersion = msg.ContentVersion |
| 1168 | } |
| 1169 | copiedParts = append(copiedParts, messageContextParts...) |
| 1170 | } |
| 1171 | if len(copiedParts) == 0 { |
| 1172 | return nil, nil |
| 1173 | } |
| 1174 | |
| 1175 | copiedParts = FilterContextPartsToLatestAgent(copiedParts) |
| 1176 | filteredContent, err := chatprompt.MarshalParts(copiedParts) |
| 1177 | if err != nil { |
| 1178 | return nil, xerrors.Errorf("marshal filtered context parts: %w", err) |
| 1179 | } |
| 1180 | |
| 1181 | msgParams := database.InsertChatMessagesParams{ //nolint:exhaustruct // Fields populated by append[User]ChatMessage. |
| 1182 | ChatID: child.ID, |
no test coverage detected