( ctx context.Context, db database.Store, chatID uuid.UUID, agentID uuid.UUID, workspaceOwnerID uuid.UUID, )
| 2789 | } |
| 2790 | |
| 2791 | func clearAgentChatContext( |
| 2792 | ctx context.Context, |
| 2793 | db database.Store, |
| 2794 | chatID uuid.UUID, |
| 2795 | agentID uuid.UUID, |
| 2796 | workspaceOwnerID uuid.UUID, |
| 2797 | ) error { |
| 2798 | return db.InTx(func(tx database.Store) error { |
| 2799 | locked, err := tx.GetChatByIDForUpdate(ctx, chatID) |
| 2800 | if err != nil { |
| 2801 | return xerrors.Errorf("lock chat: %w", err) |
| 2802 | } |
| 2803 | if !isActiveAgentChat(locked) { |
| 2804 | return errChatNotActive |
| 2805 | } |
| 2806 | if !locked.AgentID.Valid || locked.AgentID.UUID != agentID { |
| 2807 | return errChatDoesNotBelongToAgent |
| 2808 | } |
| 2809 | if locked.OwnerID != workspaceOwnerID { |
| 2810 | return errChatDoesNotBelongToWorkspaceOwner |
| 2811 | } |
| 2812 | messages, err := tx.GetChatMessagesByChatID(ctx, database.GetChatMessagesByChatIDParams{ |
| 2813 | ChatID: chatID, |
| 2814 | AfterID: 0, |
| 2815 | }) |
| 2816 | if err != nil { |
| 2817 | return xerrors.Errorf("get chat messages: %w", err) |
| 2818 | } |
| 2819 | hadInjectedContext := locked.LastInjectedContext.Valid |
| 2820 | var skillOnlyMessageIDs []int64 |
| 2821 | for _, msg := range messages { |
| 2822 | if !msg.Content.Valid { |
| 2823 | continue |
| 2824 | } |
| 2825 | hasContextFile := messageHasPartTypes(msg.Content.RawMessage, codersdk.ChatMessagePartTypeContextFile) |
| 2826 | hasSkill := messageHasPartTypes(msg.Content.RawMessage, codersdk.ChatMessagePartTypeSkill) |
| 2827 | if hasContextFile || hasSkill { |
| 2828 | hadInjectedContext = true |
| 2829 | } |
| 2830 | if hasSkill && !hasContextFile { |
| 2831 | skillOnlyMessageIDs = append(skillOnlyMessageIDs, msg.ID) |
| 2832 | } |
| 2833 | } |
| 2834 | if !hadInjectedContext { |
| 2835 | return nil |
| 2836 | } |
| 2837 | if err := tx.SoftDeleteContextFileMessages(ctx, chatID); err != nil { |
| 2838 | return xerrors.Errorf("soft delete context-file messages: %w", err) |
| 2839 | } |
| 2840 | for _, messageID := range skillOnlyMessageIDs { |
| 2841 | if err := tx.SoftDeleteChatMessageByID(ctx, messageID); err != nil { |
| 2842 | return xerrors.Errorf("soft delete context message %d: %w", messageID, err) |
| 2843 | } |
| 2844 | } |
| 2845 | // Reset provider-side Responses chaining so the next turn replays |
| 2846 | // the post-clear history instead of inheriting cleared context. |
| 2847 | if err := tx.ClearChatMessageProviderResponseIDsByChatID(ctx, chatID); err != nil { |
| 2848 | return xerrors.Errorf("clear provider response chain: %w", err) |
no test coverage detected