tryAutoPromoteQueuedMessage pops the next queued message and converts it into a pending user message inside the caller's transaction. Queued messages were already admitted through SendMessage, so this preserves FIFO order without re-checking usage limits.
( ctx context.Context, tx database.Store, chat database.Chat, )
| 5896 | // messages were already admitted through SendMessage, so this preserves FIFO |
| 5897 | // order without re-checking usage limits. |
| 5898 | func (p *Server) tryAutoPromoteQueuedMessage( |
| 5899 | ctx context.Context, |
| 5900 | tx database.Store, |
| 5901 | chat database.Chat, |
| 5902 | ) (*database.ChatMessage, []database.ChatQueuedMessage, bool, error) { |
| 5903 | logger := p.logger.With(slog.F("chat_id", chat.ID)) |
| 5904 | |
| 5905 | queuedMessages, err := tx.GetChatQueuedMessages(ctx, chat.ID) |
| 5906 | if err != nil { |
| 5907 | return nil, nil, false, xerrors.Errorf("get queued messages: %w", err) |
| 5908 | } |
| 5909 | if len(queuedMessages) == 0 { |
| 5910 | return nil, nil, false, nil |
| 5911 | } |
| 5912 | nextQueued := queuedMessages[0] |
| 5913 | effectiveModelConfigID, err := resolveQueuedMessageModelConfigID( |
| 5914 | ctx, |
| 5915 | tx, |
| 5916 | chat, |
| 5917 | nextQueued.ModelConfigID, |
| 5918 | ) |
| 5919 | if err != nil { |
| 5920 | return nil, nil, false, err |
| 5921 | } |
| 5922 | |
| 5923 | poppedQueued, err := tx.PopNextQueuedMessage(ctx, chat.ID) |
| 5924 | if err != nil { |
| 5925 | return nil, nil, false, xerrors.Errorf("pop next queued message: %w", err) |
| 5926 | } |
| 5927 | if poppedQueued.ID != nextQueued.ID { |
| 5928 | return nil, nil, false, xerrors.New("popped queued message out of order") |
| 5929 | } |
| 5930 | |
| 5931 | msgParams := database.InsertChatMessagesParams{ //nolint:exhaustruct // Fields populated by appendUserChatMessage. |
| 5932 | ChatID: chat.ID, |
| 5933 | } |
| 5934 | queuedUserMsg := newUserChatMessage( |
| 5935 | nextQueued.APIKeyID.String, |
| 5936 | pqtype.NullRawMessage{ |
| 5937 | RawMessage: nextQueued.Content, |
| 5938 | Valid: len(nextQueued.Content) > 0, |
| 5939 | }, |
| 5940 | database.ChatMessageVisibilityBoth, |
| 5941 | effectiveModelConfigID, |
| 5942 | chatprompt.CurrentContentVersion, |
| 5943 | ) |
| 5944 | queuedUserMsg = queuedUserMsg.withCreatedBy(chat.OwnerID) |
| 5945 | appendUserChatMessage(&msgParams, queuedUserMsg) |
| 5946 | msgs, err := insertChatMessageWithStore(ctx, tx, msgParams) |
| 5947 | if err != nil { |
| 5948 | return nil, nil, false, xerrors.Errorf("insert promoted message: %w", err) |
| 5949 | } |
| 5950 | msg := msgs[0] |
| 5951 | |
| 5952 | remainingQueuedMessages, err := tx.GetChatQueuedMessages(ctx, chat.ID) |
| 5953 | if err != nil { |
| 5954 | logger.Error(ctx, "failed to load remaining queued messages after auto-promotion", |
| 5955 | slog.F("queued_message_id", nextQueued.ID), slog.Error(err)) |