Add auto provider
Browse files- server.js +15 -8
- src/components/ask-ai/ask-ai.tsx +1 -1
- src/components/settings/settings.tsx +42 -24
- utils/providers.js +10 -10
server.js
CHANGED
@@ -213,15 +213,19 @@ app.post("/api/ask-ai", async (req, res) => {
|
|
213 |
const client = new InferenceClient(token);
|
214 |
let completeResponse = "";
|
215 |
|
216 |
-
const selectedProvider =
|
217 |
-
PROVIDERS.find((providerItem) => providerItem.id === provider) ??
|
218 |
-
PROVIDERS[0];
|
219 |
-
|
220 |
let TOKENS_USED = prompt?.length;
|
221 |
if (previousPrompt) TOKENS_USED += previousPrompt.length;
|
222 |
if (html) TOKENS_USED += html.length;
|
223 |
|
224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
return res.status(400).send({
|
226 |
ok: false,
|
227 |
openSelectProvider: true,
|
@@ -236,8 +240,7 @@ app.post("/api/ask-ai", async (req, res) => {
|
|
236 |
messages: [
|
237 |
{
|
238 |
role: "system",
|
239 |
-
content:
|
240 |
-
"ONLY USE HTML, CSS AND JAVASCRIPT. If you want to use ICON make sure to import the library first. Try to create the best UI possible by using only HTML, CSS and JAVASCRIPT. Also, try to ellaborate as much as you can, to create something unique. ALWAYS GIVE THE RESPONSE INTO A SINGLE HTML FILE",
|
241 |
},
|
242 |
...(previousPrompt
|
243 |
? [
|
@@ -260,7 +263,11 @@ app.post("/api/ask-ai", async (req, res) => {
|
|
260 |
content: prompt,
|
261 |
},
|
262 |
],
|
263 |
-
|
|
|
|
|
|
|
|
|
264 |
});
|
265 |
|
266 |
while (true) {
|
|
|
213 |
const client = new InferenceClient(token);
|
214 |
let completeResponse = "";
|
215 |
|
|
|
|
|
|
|
|
|
216 |
let TOKENS_USED = prompt?.length;
|
217 |
if (previousPrompt) TOKENS_USED += previousPrompt.length;
|
218 |
if (html) TOKENS_USED += html.length;
|
219 |
|
220 |
+
const DEFAULT_PROVIDER = PROVIDERS["fireworks-ai"];
|
221 |
+
const selectedProvider =
|
222 |
+
provider === "auto"
|
223 |
+
? TOKENS_USED < PROVIDERS.sambanova.max_tokens
|
224 |
+
? PROVIDERS.sambanova
|
225 |
+
: DEFAULT_PROVIDER
|
226 |
+
: PROVIDERS[provider] ?? DEFAULT_PROVIDER;
|
227 |
+
|
228 |
+
if (provider !== "auto" && TOKENS_USED >= selectedProvider.max_tokens) {
|
229 |
return res.status(400).send({
|
230 |
ok: false,
|
231 |
openSelectProvider: true,
|
|
|
240 |
messages: [
|
241 |
{
|
242 |
role: "system",
|
243 |
+
content: `ONLY USE HTML, CSS AND JAVASCRIPT. If you want to use ICON make sure to import the library first. Try to create the best UI possible by using only HTML, CSS and JAVASCRIPT. Use as much as you can TailwindCSS for the CSS, if you can't do something with TailwindCSS, then use custom CSS (make sure to import <script src="https://cdn.tailwindcss.com"></script> in the head). Also, try to ellaborate as much as you can, to create something unique. ALWAYS GIVE THE RESPONSE INTO A SINGLE HTML FILE`,
|
|
|
244 |
},
|
245 |
...(previousPrompt
|
246 |
? [
|
|
|
263 |
content: prompt,
|
264 |
},
|
265 |
],
|
266 |
+
...(selectedProvider.id !== "sambanova"
|
267 |
+
? {
|
268 |
+
max_tokens: selectedProvider.max_tokens,
|
269 |
+
}
|
270 |
+
: {}),
|
271 |
});
|
272 |
|
273 |
while (true) {
|
src/components/ask-ai/ask-ai.tsx
CHANGED
@@ -27,7 +27,7 @@ function AskAI({
|
|
27 |
const [prompt, setPrompt] = useState("");
|
28 |
const [hasAsked, setHasAsked] = useState(false);
|
29 |
const [previousPrompt, setPreviousPrompt] = useState("");
|
30 |
-
const [provider, setProvider] = useLocalStorage("provider", "
|
31 |
const [openProvider, setOpenProvider] = useState(false);
|
32 |
const [providerError, setProviderError] = useState("");
|
33 |
|
|
|
27 |
const [prompt, setPrompt] = useState("");
|
28 |
const [hasAsked, setHasAsked] = useState(false);
|
29 |
const [previousPrompt, setPreviousPrompt] = useState("");
|
30 |
+
const [provider, setProvider] = useLocalStorage("provider", "auto");
|
31 |
const [openProvider, setOpenProvider] = useState(false);
|
32 |
const [providerError, setProviderError] = useState("");
|
33 |
|
src/components/settings/settings.tsx
CHANGED
@@ -51,55 +51,73 @@ function Settings({
|
|
51 |
</span>
|
52 |
Customize Settings
|
53 |
</header>
|
54 |
-
<main className="px-4 pt-3 pb-4 space-y-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
{error !== "" && (
|
56 |
<p className="text-red-500 text-sm font-medium mb-2 flex items-center justify-between bg-red-500/10 p-2 rounded-md">
|
57 |
{error}
|
58 |
</p>
|
59 |
)}
|
60 |
<label className="block">
|
61 |
-
<p className="text-gray-
|
62 |
Inference Provider
|
63 |
</p>
|
64 |
<div className="grid grid-cols-2 gap-1.5">
|
65 |
-
{PROVIDERS.map((
|
66 |
<div
|
67 |
-
key={
|
68 |
className={classNames(
|
69 |
"text-gray-600 text-sm font-medium cursor-pointer border p-2 rounded-md flex items-center justify-start gap-2",
|
70 |
{
|
71 |
"bg-blue-500/10 border-blue-500/15 text-blue-500":
|
72 |
-
|
73 |
-
"hover:bg-gray-100 border-gray-100":
|
74 |
}
|
75 |
)}
|
76 |
onClick={() => {
|
77 |
-
onChange(
|
78 |
}}
|
79 |
>
|
80 |
<img
|
81 |
-
src={`/providers/${
|
82 |
-
alt={
|
83 |
className="size-5"
|
84 |
/>
|
85 |
-
{
|
86 |
</div>
|
87 |
))}
|
88 |
</div>
|
89 |
-
{/* <input
|
90 |
-
type="password"
|
91 |
-
autoComplete="off"
|
92 |
-
className="mr-2 border rounded-md px-3 py-1.5 border-gray-300 w-full text-sm"
|
93 |
-
placeholder="hf_******"
|
94 |
-
value={tokenStorage[0] as string}
|
95 |
-
onChange={(e) => {
|
96 |
-
if (e.target.value.length > 0) {
|
97 |
-
tokenStorage[1](e.target.value);
|
98 |
-
} else {
|
99 |
-
tokenStorage[2]();
|
100 |
-
}
|
101 |
-
}}
|
102 |
-
/> */}
|
103 |
</label>
|
104 |
</main>
|
105 |
</div>
|
|
|
51 |
</span>
|
52 |
Customize Settings
|
53 |
</header>
|
54 |
+
<main className="px-4 pt-3 pb-4 space-y-4">
|
55 |
+
{/* toggle using tailwind css */}
|
56 |
+
<div>
|
57 |
+
<div className="flex items-center justify-between">
|
58 |
+
<p className="text-gray-800 text-sm font-medium flex items-center justify-between">
|
59 |
+
Use auto-provider
|
60 |
+
</p>
|
61 |
+
<div
|
62 |
+
className={classNames(
|
63 |
+
"bg-gray-200 rounded-full w-10 h-6 flex items-center justify-between p-1 cursor-pointer transition-all duration-200",
|
64 |
+
{
|
65 |
+
"!bg-blue-500": provider === "auto",
|
66 |
+
}
|
67 |
+
)}
|
68 |
+
onClick={() => {
|
69 |
+
onChange(provider === "auto" ? "fireworks-ai" : "auto");
|
70 |
+
}}
|
71 |
+
>
|
72 |
+
<div
|
73 |
+
className={classNames(
|
74 |
+
"w-4 h-4 rounded-full shadow-md transition-all duration-200 bg-white",
|
75 |
+
{
|
76 |
+
"translate-x-4": provider !== "auto",
|
77 |
+
}
|
78 |
+
)}
|
79 |
+
/>
|
80 |
+
</div>
|
81 |
+
</div>
|
82 |
+
<p className="text-xs text-gray-500 mt-2">
|
83 |
+
We'll automatically select the best provider for you based on your
|
84 |
+
prompt.
|
85 |
+
</p>
|
86 |
+
</div>
|
87 |
{error !== "" && (
|
88 |
<p className="text-red-500 text-sm font-medium mb-2 flex items-center justify-between bg-red-500/10 p-2 rounded-md">
|
89 |
{error}
|
90 |
</p>
|
91 |
)}
|
92 |
<label className="block">
|
93 |
+
<p className="text-gray-800 text-sm font-medium mb-2 flex items-center justify-between">
|
94 |
Inference Provider
|
95 |
</p>
|
96 |
<div className="grid grid-cols-2 gap-1.5">
|
97 |
+
{Object.keys(PROVIDERS).map((id: string) => (
|
98 |
<div
|
99 |
+
key={id}
|
100 |
className={classNames(
|
101 |
"text-gray-600 text-sm font-medium cursor-pointer border p-2 rounded-md flex items-center justify-start gap-2",
|
102 |
{
|
103 |
"bg-blue-500/10 border-blue-500/15 text-blue-500":
|
104 |
+
id === provider,
|
105 |
+
"hover:bg-gray-100 border-gray-100": id !== provider,
|
106 |
}
|
107 |
)}
|
108 |
onClick={() => {
|
109 |
+
onChange(id);
|
110 |
}}
|
111 |
>
|
112 |
<img
|
113 |
+
src={`/providers/${id}.svg`}
|
114 |
+
alt={PROVIDERS[id].name}
|
115 |
className="size-5"
|
116 |
/>
|
117 |
+
{PROVIDERS[id].name}
|
118 |
</div>
|
119 |
))}
|
120 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
</label>
|
122 |
</main>
|
123 |
</div>
|
utils/providers.js
CHANGED
@@ -1,22 +1,22 @@
|
|
1 |
-
export const PROVIDERS =
|
2 |
-
{
|
3 |
name: "Fireworks AI",
|
4 |
-
id: "fireworks-ai",
|
5 |
max_tokens: 131_000,
|
|
|
6 |
},
|
7 |
-
{
|
8 |
name: "Nebius AI Studio",
|
9 |
-
id: "nebius",
|
10 |
max_tokens: 131_000,
|
|
|
11 |
},
|
12 |
-
{
|
13 |
name: "SambaNova",
|
14 |
-
id: "sambanova",
|
15 |
max_tokens: 8_000,
|
|
|
16 |
},
|
17 |
-
{
|
18 |
name: "Hyperbolic",
|
19 |
-
id: "hyperbolic",
|
20 |
max_tokens: 131_000,
|
|
|
21 |
},
|
22 |
-
|
|
|
1 |
+
export const PROVIDERS = {
|
2 |
+
"fireworks-ai": {
|
3 |
name: "Fireworks AI",
|
|
|
4 |
max_tokens: 131_000,
|
5 |
+
id: "fireworks-ai",
|
6 |
},
|
7 |
+
nebius: {
|
8 |
name: "Nebius AI Studio",
|
|
|
9 |
max_tokens: 131_000,
|
10 |
+
id: "nebius",
|
11 |
},
|
12 |
+
sambanova: {
|
13 |
name: "SambaNova",
|
|
|
14 |
max_tokens: 8_000,
|
15 |
+
id: "sambanova",
|
16 |
},
|
17 |
+
hyperbolic: {
|
18 |
name: "Hyperbolic",
|
|
|
19 |
max_tokens: 131_000,
|
20 |
+
id: "hyperbolic",
|
21 |
},
|
22 |
+
};
|