(),
+ );
const transport = useMemo(
() =>
new AssistantChatTransport({
api: "/ai/chat",
- body: () => {
+ body: () => ({
+ ...routeContextRef.current,
+ canEdit,
+ }),
+ prepareSendMessagesRequest: (options) => {
+ const messageIds = new Set(
+ options.messages.map((message) => message.id),
+ );
+ for (const messageId of questionContextSnapshotsRef.current.keys()) {
+ if (!messageIds.has(messageId)) {
+ questionContextSnapshotsRef.current.delete(messageId);
+ }
+ }
+
+ const submittedUserMessageId = getSubmittedUserMessageId(options);
const currentQuestion = routeContextRef.current.question;
- const previousQuestion = lastSubmittedQuestionRef.current;
- lastSubmittedQuestionRef.current =
- currentQuestion === null
- ? null
- : { id: currentQuestion.id, order: currentQuestion.order };
+ if (submittedUserMessageId !== null) {
+ if (currentQuestion === null) {
+ questionContextSnapshotsRef.current.delete(
+ submittedUserMessageId,
+ );
+ } else {
+ questionContextSnapshotsRef.current.set(submittedUserMessageId, {
+ messageId: submittedUserMessageId,
+ questionId: currentQuestion.id,
+ });
+ }
+ }
+
+ const questionContextSnapshots = options.messages
+ .map((message) =>
+ questionContextSnapshotsRef.current.get(message.id),
+ )
+ .filter(
+ (snapshot): snapshot is QuestionContextSnapshot =>
+ snapshot !== undefined,
+ );
return {
- ...routeContextRef.current,
- canEdit,
- questionContextChange:
- previousQuestion !== null &&
- currentQuestion !== null &&
- previousQuestion.id !== currentQuestion.id
- ? { previousQuestionOrder: previousQuestion.order }
- : undefined,
+ body: {
+ ...options.body,
+ id: options.id,
+ messages: options.messages,
+ trigger: options.trigger,
+ messageId: options.messageId,
+ metadata: options.requestMetadata,
+ questionContextSnapshots,
+ },
};
},
}),
diff --git a/src/components/ai/ai-disclaimer.tsx b/src/components/ai/ai-disclaimer.tsx
new file mode 100644
index 00000000..40410404
--- /dev/null
+++ b/src/components/ai/ai-disclaimer.tsx
@@ -0,0 +1,30 @@
+import { cn } from "@/lib/utils";
+
+interface AiDisclaimerProps {
+ className?: string;
+}
+
+export function AiDisclaimer({ className }: AiDisclaimerProps) {
+ return (
+
+ AI can make mistakes.
+
+ AI provided by{" "}
+
+ @antek
+
+ {", not Solvro."}
+
+
+ );
+}
diff --git a/src/components/ai/ai-explain-card.tsx b/src/components/ai/ai-explain-card.tsx
index d360a81b..cc77310c 100644
--- a/src/components/ai/ai-explain-card.tsx
+++ b/src/components/ai/ai-explain-card.tsx
@@ -10,6 +10,7 @@ import {
} from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
+import { AiDisclaimer } from "@/components/ai/ai-disclaimer";
import { MarkdownRenderer } from "@/components/markdown-renderer";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
@@ -280,6 +281,7 @@ function AiCardShell({
)}
{children}
+