enzostvs HF Staff commited on
Commit
8731e39
·
1 Parent(s): 3d6f13d

switch to another model automatically if model is not available atm

Browse files
app/api/ask/route.ts CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
  import { NextResponse } from "next/server";
3
  import { InferenceClient } from "@huggingface/inference";
4
 
@@ -48,96 +47,123 @@ export async function POST(request: Request) {
48
  },
49
  });
50
  (async () => {
51
- try {
52
- const chatCompletion = client.chatCompletionStream({
53
- model: model + (provider !== "auto" ? `:${provider}` : ""),
54
- messages: [
55
- {
56
- role: "system",
57
- content:
58
- files.length > 0
59
- ? FOLLOW_UP_SYSTEM_PROMPT
60
- : INITIAL_SYSTEM_PROMPT,
61
- },
62
- ...previousMessages.map((message: Message) => ({
63
- role: message.role,
64
- content: message.content,
65
- })),
66
- ...(files?.length > 0
67
- ? [
68
- {
69
- role: "user",
70
- content: `Here are the files that the user has provider:${files
71
- .map(
72
- (file: File) =>
73
- `File: ${file.path}\nContent: ${file.content}`
74
- )
75
- .join("\n")}\n\n${prompt}`,
76
- },
77
- ]
78
- : []),
79
- {
80
- role: "user",
81
- content: `${
82
- redesignMd?.url &&
83
- `Redesign the following website ${redesignMd.url}, try to use the same images and content, but you can still improve it if needed. Do the best version possibile. Here is the markdown:\n ${redesignMd.md} \n\n`
84
- }${prompt} ${
85
- medias && medias.length > 0
86
- ? `\nHere is the list of my media files: ${medias.join(
87
- ", "
88
- )}\n`
89
- : ""
90
- }`,
91
- },
92
- ],
93
- stream: true,
94
- max_tokens: 16_000,
95
- });
96
- while (true) {
97
- const { done, value } = await chatCompletion.next();
98
- if (done) {
99
- break;
100
- }
 
 
 
 
 
101
 
102
- const chunk = value.choices[0]?.delta?.content;
103
- if (chunk) {
104
- await writer.write(encoder.encode(chunk));
 
105
  }
106
- }
107
 
108
- await writer.close();
109
- } catch (error) {
110
- try {
111
  const errorMessage =
112
  error instanceof Error
113
  ? error.message
114
  : "An error occurred while processing your request";
115
- let errorPayload = "";
116
  if (
117
- errorMessage?.includes("exceeded your monthly included credits")
 
118
  ) {
119
- errorPayload = JSON.stringify({
120
- messageError: errorMessage,
121
- showProMessage: true,
122
- isError: true,
123
- });
124
- } else {
125
- errorPayload = JSON.stringify({
126
- messageError: errorMessage,
127
- isError: true,
128
- });
 
 
129
  }
130
- await writer.write(encoder.encode(`\n\n__ERROR__:${errorPayload}`));
131
- await writer.close();
132
- } catch (closeError) {
133
- console.error("Failed to send error message:", closeError);
134
  try {
135
- await writer.abort(error);
136
- } catch (abortError) {
137
- console.error("Failed to abort writer:", abortError);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  }
139
  }
140
- }
 
 
141
  })();
142
 
143
  return response;
 
 
1
  import { NextResponse } from "next/server";
2
  import { InferenceClient } from "@huggingface/inference";
3
 
 
47
  },
48
  });
49
  (async () => {
50
+ let hasRetried = false;
51
+ let currentModel = model;
52
+ let currentProvider = provider;
53
+
54
+ const tryGeneration = async (): Promise<void> => {
55
+ try {
56
+ const chatCompletion = client.chatCompletionStream({
57
+ model: currentModel + (currentProvider !== "auto" ? `:${currentProvider}` : ""),
58
+ messages: [
59
+ {
60
+ role: "system",
61
+ content:
62
+ files.length > 0
63
+ ? FOLLOW_UP_SYSTEM_PROMPT
64
+ : INITIAL_SYSTEM_PROMPT,
65
+ },
66
+ ...previousMessages.map((message: Message) => ({
67
+ role: message.role,
68
+ content: message.content,
69
+ })),
70
+ ...(files?.length > 0
71
+ ? [
72
+ {
73
+ role: "user",
74
+ content: `Here are the files that the user has provider:${files
75
+ .map(
76
+ (file: File) =>
77
+ `File: ${file.path}\nContent: ${file.content}`
78
+ )
79
+ .join("\n")}\n\n${prompt}`,
80
+ },
81
+ ]
82
+ : []),
83
+ {
84
+ role: "user",
85
+ content: `${
86
+ redesignMd?.url &&
87
+ `Redesign the following website ${redesignMd.url}, try to use the same images and content, but you can still improve it if needed. Do the best version possibile. Here is the markdown:\n ${redesignMd.md} \n\n`
88
+ }${prompt} ${
89
+ medias && medias.length > 0
90
+ ? `\nHere is the list of my media files: ${medias.join(
91
+ ", "
92
+ )}\n`
93
+ : ""
94
+ }`,
95
+ },
96
+ ],
97
+ stream: true,
98
+ max_tokens: 16_000,
99
+ });
100
+ while (true) {
101
+ const { done, value } = await chatCompletion.next();
102
+ if (done) {
103
+ break;
104
+ }
105
 
106
+ const chunk = value.choices[0]?.delta?.content;
107
+ if (chunk) {
108
+ await writer.write(encoder.encode(chunk));
109
+ }
110
  }
 
111
 
112
+ await writer.close();
113
+ } catch (error) {
 
114
  const errorMessage =
115
  error instanceof Error
116
  ? error.message
117
  : "An error occurred while processing your request";
118
+
119
  if (
120
+ !hasRetried &&
121
+ errorMessage?.includes("Failed to perform inference: Model not found")
122
  ) {
123
+ hasRetried = true;
124
+
125
+ const fallbackModel = MODELS.find((m) => m.value !== model);
126
+ if (fallbackModel) {
127
+ currentModel = fallbackModel.value;
128
+ currentProvider = fallbackModel.autoProvider ?? "auto";
129
+
130
+ const switchMessage = `\n\n_Note: The selected model was not available. Switched to \`${fallbackModel.value}\`._\n\n`;
131
+ await writer.write(encoder.encode(switchMessage));
132
+
133
+ return tryGeneration();
134
+ }
135
  }
136
+
 
 
 
137
  try {
138
+ let errorPayload = "";
139
+ if (
140
+ errorMessage?.includes("exceeded your monthly included credits")
141
+ ) {
142
+ errorPayload = JSON.stringify({
143
+ messageError: errorMessage,
144
+ showProMessage: true,
145
+ isError: true,
146
+ });
147
+ } else {
148
+ errorPayload = JSON.stringify({
149
+ messageError: errorMessage,
150
+ isError: true,
151
+ });
152
+ }
153
+ await writer.write(encoder.encode(`\n\n__ERROR__:${errorPayload}`));
154
+ await writer.close();
155
+ } catch (closeError) {
156
+ console.error("Failed to send error message:", closeError);
157
+ try {
158
+ await writer.abort(error);
159
+ } catch (abortError) {
160
+ console.error("Failed to abort writer:", abortError);
161
+ }
162
  }
163
  }
164
+ };
165
+
166
+ await tryGeneration();
167
  })();
168
 
169
  return response;
components/ask-ai/ask-ai-landing.tsx CHANGED
@@ -36,7 +36,7 @@ export function AskAiLanding({ className }: { className?: string }) {
36
  onKeyDown={(e) => {
37
  if (e.key === "Enter" && !e.shiftKey) {
38
  e.preventDefault();
39
- router.push(`/new?prompt=${prompt}`);
40
  }
41
  }}
42
  />
@@ -54,7 +54,7 @@ export function AskAiLanding({ className }: { className?: string }) {
54
  size="icon-sm"
55
  className="rounded-full!"
56
  onClick={() => {
57
- router.push(`/new?prompt=${prompt}`);
58
  }}
59
  >
60
  <ArrowUp />
 
36
  onKeyDown={(e) => {
37
  if (e.key === "Enter" && !e.shiftKey) {
38
  e.preventDefault();
39
+ router.push(`/deepsite/new?prompt=${prompt}`);
40
  }
41
  }}
42
  />
 
54
  size="icon-sm"
55
  className="rounded-full!"
56
  onClick={() => {
57
+ router.push(`/deepsite/new?prompt=${prompt}`);
58
  }}
59
  >
60
  <ArrowUp />
components/ask-ai/ask-ai.tsx CHANGED
@@ -69,13 +69,16 @@ export function AskAI({
69
  if (initialPrompt && initialPrompt.trim() !== "" && isNew) {
70
  setTimeout(() => {
71
  if (isHistoryView) return;
72
- callAi({
73
- prompt: initialPrompt,
74
- model,
75
- onComplete,
76
- provider,
77
- });
78
- router.replace("/new");
 
 
 
79
  }, 200);
80
  }
81
  });
@@ -85,14 +88,17 @@ export function AskAI({
85
  if (contentEditableRef.current) {
86
  contentEditableRef.current.innerHTML = "";
87
  }
88
- callAi({
89
- prompt,
90
- model,
91
- onComplete,
92
- provider,
93
- redesignMd,
94
- medias: selectedMedias ?? [],
95
- });
 
 
 
96
  if (selectedMedias.length > 0) setSelectedMedias([]);
97
  if (redesignMd) setRedesignMd(null);
98
  };
 
69
  if (initialPrompt && initialPrompt.trim() !== "" && isNew) {
70
  setTimeout(() => {
71
  if (isHistoryView) return;
72
+ callAi(
73
+ {
74
+ prompt: initialPrompt,
75
+ model,
76
+ onComplete,
77
+ provider,
78
+ },
79
+ setModel
80
+ );
81
+ router.replace("/deepsite/new");
82
  }, 200);
83
  }
84
  });
 
88
  if (contentEditableRef.current) {
89
  contentEditableRef.current.innerHTML = "";
90
  }
91
+ callAi(
92
+ {
93
+ prompt,
94
+ model,
95
+ onComplete,
96
+ provider,
97
+ redesignMd,
98
+ medias: selectedMedias ?? [],
99
+ },
100
+ setModel
101
+ );
102
  if (selectedMedias.length > 0) setSelectedMedias([]);
103
  if (redesignMd) setRedesignMd(null);
104
  };
components/ask-ai/useGeneration.ts CHANGED
@@ -18,7 +18,7 @@ export const useGeneration = (projectName: string) => {
18
  const audio = useRef<HTMLAudioElement>(null);
19
  const queryClient = useQueryClient();
20
  const abortController = useRef<AbortController | null>(null);
21
- const [, setStoredMessages, clearStoredMessages] = useLocalStorage<Message[]>(
22
  `messages-${projectName}`,
23
  []
24
  );
@@ -204,7 +204,7 @@ export const useGeneration = (projectName: string) => {
204
  medias?: string[] | null;
205
  onComplete: () => void;
206
  provider?: ProviderType;
207
- }) => {
208
  setIsLoading(true);
209
  const messages = getMessages();
210
  const files = getFiles();
@@ -361,6 +361,15 @@ export const useGeneration = (projectName: string) => {
361
  }
362
  }
363
  }
 
 
 
 
 
 
 
 
 
364
 
365
  const files = getFiles();
366
  const { messageContent, files: newFiles } = formatResponse(
 
18
  const audio = useRef<HTMLAudioElement>(null);
19
  const queryClient = useQueryClient();
20
  const abortController = useRef<AbortController | null>(null);
21
+ const [, setStoredMessages] = useLocalStorage<Message[]>(
22
  `messages-${projectName}`,
23
  []
24
  );
 
204
  medias?: string[] | null;
205
  onComplete: () => void;
206
  provider?: ProviderType;
207
+ }, setModel: (model: string) => void) => {
208
  setIsLoading(true);
209
  const messages = getMessages();
210
  const files = getFiles();
 
361
  }
362
  }
363
  }
364
+ if (completeResponse.includes("_Note: The selected model was not available. Switched to")) {
365
+ const newModel = completeResponse.match(/The selected model was not available. Switched to (.+)/)?.[1].replace(/`/g, "").replace(" ", "").replace(/\.|_$/g, "");
366
+ if (newModel) {
367
+ setModel(newModel);
368
+ updateMessage(currentMessages[currentMessages.length - 1].id, {
369
+ model: newModel,
370
+ });
371
+ }
372
+ }
373
 
374
  const files = getFiles();
375
  const { messageContent, files: newFiles } = formatResponse(
components/not-authorized.tsx CHANGED
@@ -1,5 +1,5 @@
1
  "use client";
2
- import { useEffect, useState } from "react";
3
  import Image from "next/image";
4
  import { Button } from "./ui/button";
5
  import Link from "next/link";
@@ -114,11 +114,14 @@ export const NotAuthorizedDomain = () => {
114
  <p className="text-lg text-muted-foreground mb-6">
115
  Unfortunately, you don&apos;t have access to DeepSite from this
116
  domain:{" "}
117
- <span className="font-mono font-semibold bg-indigo-500/10 border-2 border-indigo-500/10 text-indigo-500 text-base px-2 py-1 rounded-md">
118
- {window.location.hostname}
119
- </span>
 
 
120
  .
121
  </p>
 
122
  <Link href="https://huggingface.co/deepsite" target="_blank">
123
  <Button size="lg" className="text-base!">
124
  Go to DeepSite
 
1
  "use client";
2
+ import { useState } from "react";
3
  import Image from "next/image";
4
  import { Button } from "./ui/button";
5
  import Link from "next/link";
 
114
  <p className="text-lg text-muted-foreground mb-6">
115
  Unfortunately, you don&apos;t have access to DeepSite from this
116
  domain:{" "}
117
+ {open && (
118
+ <span className="font-mono font-semibold bg-indigo-500/10 border-2 border-indigo-500/10 text-indigo-500 text-base px-2 py-1 rounded-md">
119
+ {window?.location?.hostname ?? "unknown domain"}
120
+ </span>
121
+ )}
122
  .
123
  </p>
124
+
125
  <Link href="https://huggingface.co/deepsite" target="_blank">
126
  <Button size="lg" className="text-base!">
127
  Go to DeepSite
components/user-menu/index.tsx CHANGED
@@ -203,7 +203,7 @@ export function UserMenu() {
203
  </Link>
204
  )}
205
  <Link
206
- href="/new"
207
  className="text-xs text-muted-foreground hover:text-primary flex items-center justify-start gap-1"
208
  >
209
  New project
 
203
  </Link>
204
  )}
205
  <Link
206
+ href="/deepsite/new"
207
  className="text-xs text-muted-foreground hover:text-primary flex items-center justify-start gap-1"
208
  >
209
  New project