@chat-js/cli 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1163 -959
- package/package.json +1 -1
- package/templates/chat-app/app/(auth)/device-login/page.tsx +37 -0
- package/templates/chat-app/app/(auth)/login/page.tsx +26 -2
- package/templates/chat-app/app/(auth)/register/page.tsx +0 -12
- package/templates/chat-app/app/(chat)/api/chat/filter-reasoning-parts.ts +1 -1
- package/templates/chat-app/app/(chat)/api/chat/route.ts +13 -5
- package/templates/chat-app/app/(chat)/layout.tsx +4 -1
- package/templates/chat-app/app/api/trpc/[trpc]/route.ts +1 -0
- package/templates/chat-app/app/globals.css +9 -9
- package/templates/chat-app/app/layout.tsx +4 -2
- package/templates/chat-app/biome.jsonc +3 -3
- package/templates/chat-app/chat.config.ts +144 -141
- package/templates/chat-app/components/ai-elements/prompt-input.tsx +1 -1
- package/templates/chat-app/components/anonymous-session-init.tsx +10 -6
- package/templates/chat-app/components/artifact-actions.tsx +81 -18
- package/templates/chat-app/components/artifact-panel.tsx +142 -41
- package/templates/chat-app/components/attachment-list.tsx +1 -1
- package/templates/chat-app/components/{social-auth-providers.tsx → auth-providers.tsx} +49 -4
- package/templates/chat-app/components/chat/chat-welcome.tsx +3 -3
- package/templates/chat-app/components/chat-menu-items.tsx +1 -1
- package/templates/chat-app/components/chat-sync.tsx +3 -8
- package/templates/chat-app/components/console.tsx +9 -9
- package/templates/chat-app/components/context-usage.tsx +2 -2
- package/templates/chat-app/components/create-artifact.tsx +15 -5
- package/templates/chat-app/components/data-stream-handler.tsx +57 -16
- package/templates/chat-app/components/device-login-page.tsx +191 -0
- package/templates/chat-app/components/diffview.tsx +8 -2
- package/templates/chat-app/components/electron-auth-handler.tsx +184 -0
- package/templates/chat-app/components/electron-auth-ui.tsx +121 -0
- package/templates/chat-app/components/favicon-group.tsx +1 -1
- package/templates/chat-app/components/feedback-actions.tsx +1 -1
- package/templates/chat-app/components/greeting.tsx +1 -1
- package/templates/chat-app/components/interactive-chart-impl.tsx +3 -4
- package/templates/chat-app/components/interactive-charts.tsx +1 -1
- package/templates/chat-app/components/login-form.tsx +52 -10
- package/templates/chat-app/components/message-editor.tsx +4 -5
- package/templates/chat-app/components/model-selector.tsx +661 -655
- package/templates/chat-app/components/multimodal-input.tsx +13 -10
- package/templates/chat-app/components/parallel-response-cards.tsx +53 -35
- package/templates/chat-app/components/part/code-execution.tsx +8 -2
- package/templates/chat-app/components/part/document-common.tsx +1 -1
- package/templates/chat-app/components/part/document-preview.tsx +5 -5
- package/templates/chat-app/components/part/retrieve-url.tsx +12 -12
- package/templates/chat-app/components/part/text-message-part.tsx +13 -9
- package/templates/chat-app/components/project-chat-item.tsx +1 -1
- package/templates/chat-app/components/project-menu-items.tsx +1 -1
- package/templates/chat-app/components/research-task.tsx +1 -1
- package/templates/chat-app/components/research-tasks.tsx +1 -1
- package/templates/chat-app/components/retry-button.tsx +1 -1
- package/templates/chat-app/components/sandbox.tsx +1 -1
- package/templates/chat-app/components/sheet-editor.tsx +7 -7
- package/templates/chat-app/components/sidebar-chats-list.tsx +1 -1
- package/templates/chat-app/components/sidebar-toggle.tsx +15 -2
- package/templates/chat-app/components/sidebar-top-row.tsx +27 -12
- package/templates/chat-app/components/sidebar-user-nav.tsx +10 -1
- package/templates/chat-app/components/signup-form.tsx +49 -10
- package/templates/chat-app/components/sources.tsx +4 -4
- package/templates/chat-app/components/text-editor.tsx +5 -2
- package/templates/chat-app/components/toolbar.tsx +3 -3
- package/templates/chat-app/components/ui/sidebar.tsx +0 -1
- package/templates/chat-app/components/upgrade-cta/limit-display.tsx +1 -1
- package/templates/chat-app/components/user-message.tsx +135 -134
- package/templates/chat-app/electron.d.ts +41 -0
- package/templates/chat-app/evals/my-eval.eval.ts +3 -1
- package/templates/chat-app/hooks/use-artifact.tsx +13 -13
- package/templates/chat-app/lib/ai/gateways/provider-types.ts +19 -10
- package/templates/chat-app/lib/ai/stream-errors.test.ts +72 -0
- package/templates/chat-app/lib/ai/stream-errors.ts +94 -0
- package/templates/chat-app/lib/ai/tools/code-execution.javascript.ts +171 -0
- package/templates/chat-app/lib/ai/tools/code-execution.python.ts +336 -0
- package/templates/chat-app/lib/ai/tools/code-execution.shared.test.ts +71 -0
- package/templates/chat-app/lib/ai/tools/code-execution.shared.ts +59 -0
- package/templates/chat-app/lib/ai/tools/code-execution.ts +62 -391
- package/templates/chat-app/lib/ai/tools/code-execution.types.ts +24 -0
- package/templates/chat-app/lib/ai/tools/steps/multi-query-web-search.ts +3 -2
- package/templates/chat-app/lib/anonymous-session-client.ts +0 -3
- package/templates/chat-app/lib/artifacts/code/client.tsx +35 -5
- package/templates/chat-app/lib/artifacts/sheet/client.tsx +11 -3
- package/templates/chat-app/lib/auth-client.ts +23 -1
- package/templates/chat-app/lib/auth.ts +18 -1
- package/templates/chat-app/lib/blob.ts +1 -1
- package/templates/chat-app/lib/clone-messages.ts +1 -1
- package/templates/chat-app/lib/config-schema.ts +13 -1
- package/templates/chat-app/lib/constants.ts +3 -4
- package/templates/chat-app/lib/db/migrations/meta/0044_snapshot.json +42 -129
- package/templates/chat-app/lib/db/migrations/meta/_journal.json +1 -1
- package/templates/chat-app/lib/editor/config.ts +4 -4
- package/templates/chat-app/lib/electron-auth.ts +96 -0
- package/templates/chat-app/lib/env-schema.ts +33 -4
- package/templates/chat-app/lib/message-conversion.ts +1 -1
- package/templates/chat-app/lib/playwright-test-environment.ts +18 -0
- package/templates/chat-app/lib/social-auth.ts +5 -0
- package/templates/chat-app/lib/stores/hooks-threads.ts +2 -1
- package/templates/chat-app/lib/stores/with-threads.test.ts +1 -1
- package/templates/chat-app/lib/stores/with-threads.ts +5 -6
- package/templates/chat-app/lib/stores/with-tracing.ts +1 -1
- package/templates/chat-app/lib/thread-utils.ts +19 -21
- package/templates/chat-app/lib/utils/download-assets.ts +6 -7
- package/templates/chat-app/lib/utils/rate-limit.ts +9 -3
- package/templates/chat-app/package.json +20 -18
- package/templates/chat-app/playwright.config.ts +0 -19
- package/templates/chat-app/providers/chat-input-provider.tsx +1 -1
- package/templates/chat-app/proxy.ts +28 -3
- package/templates/chat-app/scripts/check-env.ts +10 -0
- package/templates/chat-app/trpc/server.tsx +7 -2
- package/templates/chat-app/tsconfig.json +2 -1
- package/templates/chat-app/vercel.json +0 -10
- package/templates/electron/CHANGELOG.md +7 -0
- package/templates/electron/README.md +54 -0
- package/templates/electron/entitlements.mac.plist +10 -0
- package/templates/electron/forge.config.ts +157 -0
- package/templates/electron/icon.png +0 -0
- package/templates/electron/package.json +53 -0
- package/templates/electron/scripts/generate-icons.test.js +37 -0
- package/templates/electron/scripts/generate-icons.ts +29 -0
- package/templates/electron/scripts/run-forge.cjs +28 -0
- package/templates/electron/scripts/write-branding.ts +18 -0
- package/templates/electron/src/config.ts +16 -0
- package/templates/electron/src/lib/auth-client.ts +64 -0
- package/templates/electron/src/main.ts +670 -0
- package/templates/electron/src/preload.d.ts +27 -0
- package/templates/electron/src/preload.ts +25 -0
- package/templates/electron/tsconfig.json +18 -0
package/package.json
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { headers } from "next/headers";
|
|
3
|
+
import { redirect } from "next/navigation";
|
|
4
|
+
import { DeviceLoginPage } from "@/components/device-login-page";
|
|
5
|
+
import { auth } from "@/lib/auth";
|
|
6
|
+
import { config } from "@/lib/config";
|
|
7
|
+
import { toSearchParamRecord } from "@/lib/electron-auth";
|
|
8
|
+
|
|
9
|
+
export const metadata: Metadata = {
|
|
10
|
+
title: "Device Login",
|
|
11
|
+
description: "Sign in for the desktop app",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default async function DeviceLoginRoute({
|
|
15
|
+
searchParams,
|
|
16
|
+
}: {
|
|
17
|
+
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
|
18
|
+
}) {
|
|
19
|
+
if (!config.desktopApp.enabled) {
|
|
20
|
+
redirect("/login");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const resolvedSearchParams = await searchParams;
|
|
24
|
+
const query = toSearchParamRecord(resolvedSearchParams);
|
|
25
|
+
const isCompletedView = query.done === "1";
|
|
26
|
+
const queryString = new URLSearchParams(query).toString();
|
|
27
|
+
const currentHref = queryString
|
|
28
|
+
? `/device-login?${queryString}`
|
|
29
|
+
: "/device-login";
|
|
30
|
+
const session = await auth.api.getSession({ headers: await headers() });
|
|
31
|
+
|
|
32
|
+
if (!(session?.user || isCompletedView)) {
|
|
33
|
+
redirect(`/login?returnTo=${encodeURIComponent(currentHref)}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return <DeviceLoginPage />;
|
|
37
|
+
}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { ChevronLeft } from "lucide-react";
|
|
2
2
|
import type { Metadata } from "next";
|
|
3
|
+
import { headers } from "next/headers";
|
|
3
4
|
import Link from "next/link";
|
|
5
|
+
import { ElectronTransferUser } from "@/components/electron-auth-ui";
|
|
4
6
|
import { LoginForm } from "@/components/login-form";
|
|
5
7
|
import { buttonVariants } from "@/components/ui/button";
|
|
8
|
+
import { auth } from "@/lib/auth";
|
|
9
|
+
import { config } from "@/lib/config";
|
|
10
|
+
import {
|
|
11
|
+
ELECTRON_AUTH_CLIENT_ID,
|
|
12
|
+
toSearchParamRecord,
|
|
13
|
+
} from "@/lib/electron-auth";
|
|
6
14
|
import { cn } from "@/lib/utils";
|
|
7
15
|
|
|
8
16
|
export const metadata: Metadata = {
|
|
@@ -10,7 +18,19 @@ export const metadata: Metadata = {
|
|
|
10
18
|
description: "Login to your account",
|
|
11
19
|
};
|
|
12
20
|
|
|
13
|
-
export default function LoginPage(
|
|
21
|
+
export default async function LoginPage({
|
|
22
|
+
searchParams,
|
|
23
|
+
}: {
|
|
24
|
+
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
|
25
|
+
}) {
|
|
26
|
+
const resolvedSearchParams = await searchParams;
|
|
27
|
+
const query = toSearchParamRecord(resolvedSearchParams);
|
|
28
|
+
const isElectronTransfer =
|
|
29
|
+
config.desktopApp.enabled && query.client_id === ELECTRON_AUTH_CLIENT_ID;
|
|
30
|
+
const session = isElectronTransfer
|
|
31
|
+
? await auth.api.getSession({ headers: await headers() })
|
|
32
|
+
: null;
|
|
33
|
+
|
|
14
34
|
return (
|
|
15
35
|
<div className="container mx-auto flex h-dvh w-screen flex-col items-center justify-center">
|
|
16
36
|
<Link
|
|
@@ -24,7 +44,11 @@ export default function LoginPage() {
|
|
|
24
44
|
Back
|
|
25
45
|
</Link>
|
|
26
46
|
<div className="mx-auto flex w-full flex-col items-center justify-center sm:w-[420px]">
|
|
27
|
-
|
|
47
|
+
{session?.user && isElectronTransfer ? (
|
|
48
|
+
<ElectronTransferUser query={query} session={session} />
|
|
49
|
+
) : (
|
|
50
|
+
<LoginForm className="w-full" />
|
|
51
|
+
)}
|
|
28
52
|
</div>
|
|
29
53
|
</div>
|
|
30
54
|
);
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import type { Metadata } from "next";
|
|
2
|
-
import Link from "next/link";
|
|
3
2
|
import { SignupForm } from "@/components/signup-form";
|
|
4
|
-
import { buttonVariants } from "@/components/ui/button";
|
|
5
|
-
import { cn } from "@/lib/utils";
|
|
6
3
|
|
|
7
4
|
export const metadata: Metadata = {
|
|
8
5
|
title: "Create an account",
|
|
@@ -12,15 +9,6 @@ export const metadata: Metadata = {
|
|
|
12
9
|
export default function RegisterPage() {
|
|
13
10
|
return (
|
|
14
11
|
<div className="container m-auto flex h-dvh w-screen flex-col items-center justify-center px-4">
|
|
15
|
-
<Link
|
|
16
|
-
className={cn(
|
|
17
|
-
buttonVariants({ variant: "ghost" }),
|
|
18
|
-
"absolute top-4 right-4 md:top-8 md:right-8"
|
|
19
|
-
)}
|
|
20
|
-
href="/login"
|
|
21
|
-
>
|
|
22
|
-
Login
|
|
23
|
-
</Link>
|
|
24
12
|
<div className="mx-auto w-full sm:w-[480px]">
|
|
25
13
|
<SignupForm />
|
|
26
14
|
</div>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Note: data-* parts are handled by convertToModelMessages({ convertDataPart: () => undefined })
|
|
7
7
|
*/
|
|
8
|
-
export function filterPartsForLLM<T extends { parts:
|
|
8
|
+
export function filterPartsForLLM<T extends { parts: Array<{ type: string }> }>(
|
|
9
9
|
messages: T[]
|
|
10
10
|
): T[] {
|
|
11
11
|
return messages.map((message) => ({
|
|
@@ -25,11 +25,12 @@ import {
|
|
|
25
25
|
streamFollowupSuggestions,
|
|
26
26
|
} from "@/lib/ai/followup-suggestions";
|
|
27
27
|
import { systemPrompt } from "@/lib/ai/prompts";
|
|
28
|
+
import { getStreamErrorMessage } from "@/lib/ai/stream-errors";
|
|
28
29
|
import { calculateMessagesTokens } from "@/lib/ai/token-utils";
|
|
29
30
|
import { allTools } from "@/lib/ai/tools/tools-definitions";
|
|
30
31
|
import {
|
|
31
|
-
getPrimarySelectedModelId,
|
|
32
32
|
type ChatMessage,
|
|
33
|
+
getPrimarySelectedModelId,
|
|
33
34
|
type ToolName,
|
|
34
35
|
} from "@/lib/ai/types";
|
|
35
36
|
import {
|
|
@@ -227,7 +228,9 @@ function resolveSelectedModelId({
|
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
if (requestSelectedModelId) {
|
|
230
|
-
if (!selectedModel || typeof selectedModel !== "object")
|
|
231
|
+
if (!selectedModel || typeof selectedModel !== "object") {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
231
234
|
const requestedCount = selectedModel[requestSelectedModelId];
|
|
232
235
|
return requestedCount && requestedCount > 0 ? requestSelectedModelId : null;
|
|
233
236
|
}
|
|
@@ -480,7 +483,10 @@ async function createChatStream({
|
|
|
480
483
|
if (!isAnonymous) {
|
|
481
484
|
after(() =>
|
|
482
485
|
Promise.resolve(
|
|
483
|
-
updateMessageActiveStreamId({
|
|
486
|
+
updateMessageActiveStreamId({
|
|
487
|
+
id: messageId,
|
|
488
|
+
activeStreamId: null,
|
|
489
|
+
})
|
|
484
490
|
).catch((dbError) => {
|
|
485
491
|
log.error(
|
|
486
492
|
{ error: dbError },
|
|
@@ -491,7 +497,7 @@ async function createChatStream({
|
|
|
491
497
|
}
|
|
492
498
|
|
|
493
499
|
log.error({ error }, "onError");
|
|
494
|
-
return
|
|
500
|
+
return getStreamErrorMessage(error);
|
|
495
501
|
},
|
|
496
502
|
});
|
|
497
503
|
|
|
@@ -794,7 +800,9 @@ async function finalizeMessageAndCredits({
|
|
|
794
800
|
metadata: {
|
|
795
801
|
...assistantMessage.metadata,
|
|
796
802
|
parallelGroupId:
|
|
797
|
-
parallelGroupId ??
|
|
803
|
+
parallelGroupId ??
|
|
804
|
+
assistantMessage.metadata.parallelGroupId ??
|
|
805
|
+
null,
|
|
798
806
|
parallelIndex:
|
|
799
807
|
parallelIndex ?? assistantMessage.metadata.parallelIndex ?? null,
|
|
800
808
|
isPrimaryParallel:
|
|
@@ -5,6 +5,7 @@ import { KeyboardShortcuts } from "@/components/keyboard-shortcuts";
|
|
|
5
5
|
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
|
|
6
6
|
import type { AppModelId } from "@/lib/ai/app-model-id";
|
|
7
7
|
import { config } from "@/lib/config";
|
|
8
|
+
import { isPlaywrightTestEnvironment } from "@/lib/constants";
|
|
8
9
|
import { ANONYMOUS_LIMITS } from "@/lib/types/anonymous";
|
|
9
10
|
import { ChatModelsProvider } from "@/providers/chat-models-provider";
|
|
10
11
|
import { DefaultModelProvider } from "@/providers/default-model-provider";
|
|
@@ -24,7 +25,9 @@ export default async function ChatLayout({
|
|
|
24
25
|
headers(),
|
|
25
26
|
getChatModels(),
|
|
26
27
|
]);
|
|
27
|
-
const session =
|
|
28
|
+
const session = isPlaywrightTestEnvironment
|
|
29
|
+
? null
|
|
30
|
+
: await auth.api.getSession({ headers: headersRes });
|
|
28
31
|
const isCollapsed = cookieStore.get("sidebar:state")?.value !== "true";
|
|
29
32
|
|
|
30
33
|
const cookieModel = cookieStore.get("chat-model")?.value;
|
|
@@ -245,17 +245,17 @@
|
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
:root {
|
|
248
|
-
--background: hsl(0 0%
|
|
248
|
+
--background: hsl(0 0% 100%);
|
|
249
249
|
--foreground: hsl(0 0% 20%);
|
|
250
|
-
--card: hsl(0 0%
|
|
250
|
+
--card: hsl(0 0% 97.0392%);
|
|
251
251
|
--card-foreground: hsl(0 0% 20%);
|
|
252
|
-
--popover: hsl(0 0%
|
|
252
|
+
--popover: hsl(0 0% 97.0392%);
|
|
253
253
|
--popover-foreground: hsl(0 0% 20%);
|
|
254
254
|
--primary: hsl(217.2193 91.2195% 59.8039%);
|
|
255
255
|
--primary-foreground: hsl(0 0% 100%);
|
|
256
|
-
--secondary: hsl(
|
|
256
|
+
--secondary: hsl(0 0% 97.0392%);
|
|
257
257
|
--secondary-foreground: hsl(215 13.7931% 34.1176%);
|
|
258
|
-
--muted: hsl(
|
|
258
|
+
--muted: hsl(0 0% 97.0392%);
|
|
259
259
|
--muted-foreground: hsl(220 8.9362% 46.0784%);
|
|
260
260
|
--accent: hsl(204 93.75% 93.7255%);
|
|
261
261
|
--accent-foreground: hsl(224.4444 64.2857% 32.9412%);
|
|
@@ -269,7 +269,7 @@
|
|
|
269
269
|
--chart-3: hsl(224.2781 76.3265% 48.0392%);
|
|
270
270
|
--chart-4: hsl(225.931 70.7317% 40.1961%);
|
|
271
271
|
--chart-5: hsl(224.4444 64.2857% 32.9412%);
|
|
272
|
-
--sidebar: hsl(
|
|
272
|
+
--sidebar: hsl(0 0% 97.0392%);
|
|
273
273
|
--sidebar-foreground: hsl(0 0% 20%);
|
|
274
274
|
--sidebar-primary: hsl(217.2193 91.2195% 59.8039%);
|
|
275
275
|
--sidebar-primary-foreground: hsl(0 0% 100%);
|
|
@@ -383,13 +383,13 @@
|
|
|
383
383
|
|
|
384
384
|
.cm-editor,
|
|
385
385
|
.cm-gutters {
|
|
386
|
-
@apply bg-
|
|
386
|
+
@apply bg-card! outline-hidden! selection:bg-zinc-900!;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
.ͼo.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground,
|
|
390
390
|
.ͼo.cm-selectionBackground,
|
|
391
391
|
.ͼo.cm-content::selection {
|
|
392
|
-
@apply bg-
|
|
392
|
+
@apply bg-accent!;
|
|
393
393
|
}
|
|
394
394
|
|
|
395
395
|
.cm-activeLine,
|
|
@@ -414,7 +414,7 @@
|
|
|
414
414
|
}
|
|
415
415
|
|
|
416
416
|
.suggestion-highlight {
|
|
417
|
-
@apply bg-
|
|
417
|
+
@apply bg-accent text-accent-foreground hover:bg-accent/80;
|
|
418
418
|
}
|
|
419
419
|
|
|
420
420
|
/* Lexical Editor Styles */
|
|
@@ -7,6 +7,7 @@ import Script from "next/script";
|
|
|
7
7
|
import "./globals.css";
|
|
8
8
|
import { NuqsAdapter } from "nuqs/adapters/next/app";
|
|
9
9
|
import { Toaster } from "sonner";
|
|
10
|
+
import { ElectronAuthHandler } from "@/components/electron-auth-handler";
|
|
10
11
|
import { ThemeProvider } from "@/components/theme-provider";
|
|
11
12
|
import { config } from "@/lib/config";
|
|
12
13
|
|
|
@@ -78,14 +79,15 @@ export default async function RootLayout({
|
|
|
78
79
|
<Script id="theme-color-script" strategy="beforeInteractive">
|
|
79
80
|
{THEME_COLOR_SCRIPT}
|
|
80
81
|
</Script>
|
|
81
|
-
{process.env.NODE_ENV
|
|
82
|
+
{process.env.NODE_ENV === "production" ? null : (
|
|
82
83
|
<Script
|
|
83
84
|
src="https://unpkg.com/react-scan/dist/auto.global.js"
|
|
84
85
|
strategy="beforeInteractive"
|
|
85
86
|
/>
|
|
86
|
-
)
|
|
87
|
+
)}
|
|
87
88
|
</head>
|
|
88
89
|
<body className="antialiased">
|
|
90
|
+
<ElectronAuthHandler />
|
|
89
91
|
<Script
|
|
90
92
|
src="https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"
|
|
91
93
|
strategy="afterInteractive"
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
},
|
|
18
18
|
"linter": {
|
|
19
19
|
"rules": {
|
|
20
|
-
"
|
|
21
|
-
/*
|
|
22
|
-
"
|
|
20
|
+
"style": {
|
|
21
|
+
/* Allow mixing interface and type — type is required for intersection/mapped types */
|
|
22
|
+
"useConsistentTypeDefinitions": "off"
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -9,147 +9,150 @@ const isProd = process.env.NODE_ENV === "production";
|
|
|
9
9
|
* @see https://chatjs.dev/docs/reference/config
|
|
10
10
|
*/
|
|
11
11
|
const config = defineConfig({
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
12
|
+
appPrefix: "chatjs",
|
|
13
|
+
appName: "ChatJS",
|
|
14
|
+
appTitle: "ChatJS - The prod ready AI chat app",
|
|
15
|
+
appDescription:
|
|
16
|
+
"Build and deploy AI chat applications in minutes. ChatJS provides authentication, streaming, tool calling, and all the features you need for production-ready AI conversations.",
|
|
17
|
+
appUrl: "https://www.demo.chatjs.dev",
|
|
18
|
+
organization: {
|
|
19
|
+
name: "ChatJS",
|
|
20
|
+
contact: {
|
|
21
|
+
privacyEmail: "privacy@chatjs.dev",
|
|
22
|
+
legalEmail: "legal@chatjs.dev",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
services: {
|
|
26
|
+
hosting: "Vercel",
|
|
27
|
+
aiProviders: [
|
|
28
|
+
"OpenAI",
|
|
29
|
+
"Anthropic",
|
|
30
|
+
"xAI",
|
|
31
|
+
"Google",
|
|
32
|
+
"Meta",
|
|
33
|
+
"Mistral",
|
|
34
|
+
"Alibaba",
|
|
35
|
+
"Amazon",
|
|
36
|
+
"Cohere",
|
|
37
|
+
"DeepSeek",
|
|
38
|
+
"Perplexity",
|
|
39
|
+
"Vercel",
|
|
40
|
+
"Inception",
|
|
41
|
+
"Moonshot",
|
|
42
|
+
"Morph",
|
|
43
|
+
"ZAI",
|
|
44
|
+
],
|
|
45
|
+
paymentProcessors: [],
|
|
46
|
+
},
|
|
47
|
+
features: {
|
|
48
|
+
attachments: true, // Requires BLOB_READ_WRITE_TOKEN
|
|
49
|
+
parallelResponses: true,
|
|
50
|
+
},
|
|
51
|
+
legal: {
|
|
52
|
+
minimumAge: 13,
|
|
53
|
+
governingLaw: "United States",
|
|
54
|
+
refundPolicy: "no-refunds",
|
|
55
|
+
},
|
|
56
|
+
policies: {
|
|
57
|
+
privacy: {
|
|
58
|
+
title: "Privacy Policy",
|
|
59
|
+
lastUpdated: "July 24, 2025",
|
|
60
|
+
},
|
|
61
|
+
terms: {
|
|
62
|
+
title: "Terms of Service",
|
|
63
|
+
lastUpdated: "July 24, 2025",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
authentication: {
|
|
67
|
+
google: true, // Requires AUTH_GOOGLE_ID + AUTH_GOOGLE_SECRET
|
|
68
|
+
github: true, // Requires AUTH_GITHUB_ID + AUTH_GITHUB_SECRET
|
|
69
|
+
vercel: true, // Requires VERCEL_APP_CLIENT_ID + VERCEL_APP_CLIENT_SECRET
|
|
70
|
+
},
|
|
71
|
+
desktopApp: {
|
|
72
|
+
enabled: true,
|
|
73
|
+
},
|
|
74
|
+
ai: {
|
|
75
|
+
gateway: "vercel",
|
|
76
|
+
providerOrder: [
|
|
77
|
+
"openai",
|
|
78
|
+
"anthropic",
|
|
79
|
+
"google",
|
|
80
|
+
"xai",
|
|
81
|
+
"meta",
|
|
82
|
+
"mistral",
|
|
83
|
+
"deepseek",
|
|
84
|
+
"perplexity",
|
|
85
|
+
"cohere",
|
|
86
|
+
"alibaba",
|
|
87
|
+
"amazon",
|
|
88
|
+
"inception",
|
|
89
|
+
"moonshot",
|
|
90
|
+
"morph",
|
|
91
|
+
"zai",
|
|
92
|
+
],
|
|
93
|
+
disabledModels: [],
|
|
94
|
+
anonymousModels: ["openai/gpt-5-nano"],
|
|
95
|
+
workflows: {
|
|
96
|
+
chatImageCompatible: "openai/gpt-4o-mini",
|
|
97
|
+
},
|
|
98
|
+
tools: {
|
|
99
|
+
webSearch: {
|
|
100
|
+
enabled: true, // Requires TAVILY_API_KEY or FIRECRAWL_API_KEY
|
|
101
|
+
},
|
|
102
|
+
urlRetrieval: {
|
|
103
|
+
enabled: true, // Requires FIRECRAWL_API_KEY
|
|
104
|
+
},
|
|
105
|
+
codeExecution: {
|
|
106
|
+
enabled: true, // Vercel-native, no key needed
|
|
107
|
+
},
|
|
108
|
+
mcp: {
|
|
109
|
+
enabled: true, // Requires MCP_ENCRYPTION_KEY
|
|
110
|
+
},
|
|
111
|
+
followupSuggestions: {
|
|
112
|
+
enabled: true,
|
|
113
|
+
},
|
|
114
|
+
text: {
|
|
115
|
+
polish: "openai/gpt-5-mini",
|
|
116
|
+
},
|
|
117
|
+
sheet: {
|
|
118
|
+
format: "openai/gpt-5-mini",
|
|
119
|
+
analyze: "openai/gpt-5-mini",
|
|
120
|
+
},
|
|
121
|
+
code: {
|
|
122
|
+
edits: "openai/gpt-5-mini",
|
|
123
|
+
},
|
|
124
|
+
image: {
|
|
125
|
+
enabled: true, // Requires BLOB_READ_WRITE_TOKEN
|
|
126
|
+
default: "google/gemini-3-pro-image",
|
|
127
|
+
},
|
|
128
|
+
deepResearch: {
|
|
129
|
+
enabled: true, // Requires webSearch
|
|
130
|
+
defaultModel: "openai/gpt-5-nano",
|
|
131
|
+
finalReportModel: "openai/gpt-5-mini",
|
|
132
|
+
allowClarification: true,
|
|
133
|
+
maxResearcherIterations: 1,
|
|
134
|
+
maxConcurrentResearchUnits: 2,
|
|
135
|
+
maxSearchQueries: 2,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
anonymous: {
|
|
140
|
+
credits: isProd ? 10 : 1000,
|
|
141
|
+
availableTools: [],
|
|
142
|
+
rateLimit: {
|
|
143
|
+
requestsPerMinute: isProd ? 5 : 60,
|
|
144
|
+
requestsPerMonth: isProd ? 10 : 1000,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
attachments: {
|
|
148
|
+
maxBytes: 1024 * 1024, // 1MB
|
|
149
|
+
maxDimension: 2048,
|
|
150
|
+
acceptedTypes: {
|
|
151
|
+
"image/png": [".png"],
|
|
152
|
+
"image/jpeg": [".jpg", ".jpeg"],
|
|
153
|
+
"application/pdf": [".pdf"],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
153
156
|
});
|
|
154
157
|
|
|
155
158
|
export default config;
|
|
@@ -286,7 +286,7 @@ export function PromptInputAttachment({
|
|
|
286
286
|
<HoverCardTrigger asChild>
|
|
287
287
|
<div
|
|
288
288
|
className={cn(
|
|
289
|
-
"group relative flex h-8 cursor-default select-none items-center gap-1.5 rounded-md border border-border px-1.5 font-medium text-sm transition-all hover:bg-accent hover:text-accent-foreground
|
|
289
|
+
"group relative flex h-8 cursor-default select-none items-center gap-1.5 rounded-md border border-border px-1.5 font-medium text-sm transition-all hover:bg-accent hover:text-accent-foreground",
|
|
290
290
|
className
|
|
291
291
|
)}
|
|
292
292
|
key={data.id}
|
|
@@ -13,13 +13,17 @@ import { useSession } from "@/providers/session-provider";
|
|
|
13
13
|
import { useTRPC } from "@/trpc/react";
|
|
14
14
|
|
|
15
15
|
// Schema validation function
|
|
16
|
-
function isValidAnonymousSession(obj:
|
|
16
|
+
function isValidAnonymousSession(obj: unknown): obj is AnonymousSession {
|
|
17
|
+
if (!obj || typeof obj !== "object") {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const session = obj as Partial<AnonymousSession>;
|
|
22
|
+
|
|
17
23
|
return (
|
|
18
|
-
|
|
19
|
-
typeof
|
|
20
|
-
typeof
|
|
21
|
-
typeof obj.remainingCredits === "number" &&
|
|
22
|
-
(obj.createdAt instanceof Date || typeof obj.createdAt === "string")
|
|
24
|
+
typeof session.id === "string" &&
|
|
25
|
+
typeof session.remainingCredits === "number" &&
|
|
26
|
+
(session.createdAt instanceof Date || typeof session.createdAt === "string")
|
|
23
27
|
);
|
|
24
28
|
}
|
|
25
29
|
|