* Append a message and stream the response
(message: UIMessage | ModelMessage)
| 811 | * Append a message and stream the response |
| 812 | */ |
| 813 | async append(message: UIMessage | ModelMessage): Promise<void> { |
| 814 | this.mountDevtools() |
| 815 | // Normalize the message to ensure it has id and createdAt |
| 816 | const normalizedMessage = normalizeToUIMessage(message, generateMessageId) |
| 817 | |
| 818 | // Skip system messages - they're handled via systemPrompts, not UIMessages |
| 819 | if (normalizedMessage.role === 'system') { |
| 820 | return |
| 821 | } |
| 822 | |
| 823 | // Type assertion: after checking for system, we know it's user or assistant |
| 824 | const uiMessage = normalizedMessage as UIMessage |
| 825 | |
| 826 | // Emit message appended event |
| 827 | this.events.messageAppended(uiMessage) |
| 828 | |
| 829 | // Add to messages |
| 830 | const messages = this.processor.getMessages() |
| 831 | this.processor.setMessages([...messages, uiMessage]) |
| 832 | this.devtoolsBridge.emitSnapshot() |
| 833 | |
| 834 | // If stream is in progress, queue the response for after it ends |
| 835 | if (this.isLoading) { |
| 836 | this.queuePostStreamAction(async () => { |
| 837 | await this.streamResponse() |
| 838 | }) |
| 839 | return |
| 840 | } |
| 841 | |
| 842 | await this.streamResponse() |
| 843 | } |
| 844 | |
| 845 | /** |
| 846 | * Stream a response from the LLM. |
nothing calls this directly
no test coverage detected