@chat-js/cli 0.1.3 → 0.2.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 +400 -246
- package/package.json +1 -1
- package/templates/chat-app/.claude/skiller.toml +18 -0
- package/templates/chat-app/.claude/skills/chat-context/SKILL.md +6 -0
- package/templates/chat-app/.claude/skills/chat-context/chat-context.mdc +36 -0
- package/templates/chat-app/.claude/skills/lazy-prefetch-pattern/lazy-prefetch-pattern.mdc +27 -0
- package/templates/chat-app/.claude/skills/react/react.mdc +29 -0
- package/templates/chat-app/.claude/skills/trpc-patterns/trpc-patterns.mdc +77 -0
- package/templates/chat-app/.claude/skills/typescript/typescript.mdc +53 -0
- package/templates/chat-app/.claude/skills/ultracite/ultracite.mdc +129 -0
- package/templates/chat-app/.cursor/skills/chat-context/SKILL.md +37 -0
- package/templates/chat-app/.cursor/skills/lazy-prefetch-pattern/SKILL.md +26 -0
- package/templates/chat-app/.cursor/skills/react/SKILL.md +28 -0
- package/templates/chat-app/.cursor/skills/trpc-patterns/SKILL.md +76 -0
- package/templates/chat-app/.cursor/skills/typescript/SKILL.md +52 -0
- package/templates/chat-app/.cursor/skills/ultracite/SKILL.md +128 -0
- package/templates/chat-app/app/(chat)/actions.ts +1 -1
- package/templates/chat-app/app/(chat)/api/chat/[id]/stream/route.ts +6 -5
- package/templates/chat-app/app/(chat)/api/chat/route.ts +14 -15
- package/templates/chat-app/app/(chat)/chat-providers.tsx +2 -2
- package/templates/chat-app/app/(chat)/layout.tsx +7 -6
- package/templates/chat-app/app/api/cron/cleanup/route.ts +4 -3
- package/templates/chat-app/app/globals.css +22 -22
- package/templates/chat-app/app/layout.tsx +1 -1
- package/templates/chat-app/biome.jsonc +3 -3
- package/templates/chat-app/chat.config.ts +47 -20
- package/templates/chat-app/components/anonymous-session-init.tsx +4 -12
- package/templates/chat-app/components/artifact-actions.tsx +5 -5
- package/templates/chat-app/components/artifact-panel.tsx +6 -6
- package/templates/chat-app/components/assistant-message.tsx +1 -1
- package/templates/chat-app/components/chat/chat-layout.tsx +2 -2
- package/templates/chat-app/components/chat/chat-welcome.tsx +1 -0
- package/templates/chat-app/components/chat-features-definitions.ts +11 -8
- package/templates/chat-app/components/chat-menu-items.tsx +4 -4
- package/templates/chat-app/components/chat-sync.tsx +1 -2
- package/templates/chat-app/components/clone-chat-button.tsx +2 -2
- package/templates/chat-app/components/code-editor.tsx +5 -5
- package/templates/chat-app/components/connectors-dropdown.tsx +2 -2
- package/templates/chat-app/components/console.tsx +5 -5
- package/templates/chat-app/components/create-artifact.tsx +28 -28
- package/templates/chat-app/components/data-stream-provider.tsx +2 -2
- package/templates/chat-app/components/deep-research-progress.tsx +2 -2
- package/templates/chat-app/components/delete-chat-dialog.tsx +3 -3
- package/templates/chat-app/components/delete-project-dialog.tsx +3 -3
- package/templates/chat-app/components/diffview.tsx +3 -3
- package/templates/chat-app/components/favicon-group.tsx +7 -7
- package/templates/chat-app/components/header-breadcrumb.tsx +11 -11
- package/templates/chat-app/components/image-editor.tsx +5 -5
- package/templates/chat-app/components/image-modal.tsx +4 -4
- package/templates/chat-app/components/interactive-chart-impl.tsx +269 -0
- package/templates/chat-app/components/interactive-charts.tsx +18 -246
- package/templates/chat-app/components/lexical-chat-input.tsx +10 -10
- package/templates/chat-app/components/message-editor.tsx +3 -3
- package/templates/chat-app/components/message-parts.tsx +8 -3
- package/templates/chat-app/components/messages-pane.tsx +4 -4
- package/templates/chat-app/components/messages.tsx +5 -5
- package/templates/chat-app/components/model-selector.tsx +4 -1
- package/templates/chat-app/components/multimodal-input.tsx +14 -5
- package/templates/chat-app/components/part/code-execution.tsx +4 -1
- package/templates/chat-app/components/part/document-common.tsx +8 -8
- package/templates/chat-app/components/part/document-preview.tsx +34 -16
- package/templates/chat-app/components/part/document-tool.tsx +3 -3
- package/templates/chat-app/components/part/dynamic-tool.tsx +3 -3
- package/templates/chat-app/components/part/generate-video.tsx +54 -0
- package/templates/chat-app/components/part/message-reasoning.tsx +3 -3
- package/templates/chat-app/components/project-details-dialog.tsx +4 -4
- package/templates/chat-app/components/project-home.tsx +1 -0
- package/templates/chat-app/components/project-icon-picker.tsx +5 -5
- package/templates/chat-app/components/project-icon.tsx +4 -4
- package/templates/chat-app/components/project-menu-items.tsx +3 -3
- package/templates/chat-app/components/research-tasks.tsx +3 -3
- package/templates/chat-app/components/sandbox.tsx +4 -4
- package/templates/chat-app/components/search-chats-dialog.tsx +11 -11
- package/templates/chat-app/components/settings/connectors-settings.tsx +1 -1
- package/templates/chat-app/components/settings/settings-nav.tsx +1 -1
- package/templates/chat-app/components/sheet-editor.tsx +5 -5
- package/templates/chat-app/components/sidebar-chats-list.tsx +5 -5
- package/templates/chat-app/components/suggested-actions.tsx +3 -3
- package/templates/chat-app/components/text-editor.tsx +5 -5
- package/templates/chat-app/components/toolbar.tsx +6 -6
- package/templates/chat-app/components/upgrade-cta/login-cta-banner.tsx +5 -5
- package/templates/chat-app/components/upgrade-cta/login-prompt.tsx +4 -4
- package/templates/chat-app/components/upgrade-cta/share-menu-item.tsx +3 -3
- package/templates/chat-app/components/user-message.tsx +3 -3
- package/templates/chat-app/components/version-footer.tsx +4 -4
- package/templates/chat-app/hooks/chat-sync-hooks.ts +0 -55
- package/templates/chat-app/hooks/use-artifact.tsx +3 -3
- package/templates/chat-app/hooks/use-auto-focus.ts +37 -7
- package/templates/chat-app/hooks/use-media-query.tsx +2 -4
- package/templates/chat-app/lib/ai/active-gateway.ts +1 -1
- package/templates/chat-app/lib/ai/ai-gateway-models-schemas.ts +30 -6
- package/templates/chat-app/lib/ai/app-model-id.ts +1 -1
- package/templates/chat-app/lib/ai/app-models.ts +4 -4
- package/templates/chat-app/lib/ai/eval-agent.ts +5 -5
- package/templates/chat-app/lib/ai/followup-suggestions.ts +1 -1
- package/templates/chat-app/lib/ai/gateway-model-defaults.ts +131 -41
- package/templates/chat-app/lib/ai/gateways/gateway-provider.ts +10 -6
- package/templates/chat-app/lib/ai/gateways/openai-compatible-gateway.ts +9 -4
- package/templates/chat-app/lib/ai/gateways/openai-gateway.ts +9 -4
- package/templates/chat-app/lib/ai/gateways/openrouter-gateway.ts +17 -12
- package/templates/chat-app/lib/ai/gateways/registry.ts +9 -0
- package/templates/chat-app/lib/ai/gateways/vercel-gateway.ts +36 -4
- package/templates/chat-app/lib/ai/mcp/cache.ts +13 -13
- package/templates/chat-app/lib/ai/model-data.ts +21 -20
- package/templates/chat-app/lib/ai/models.generated.ts +4397 -3592
- package/templates/chat-app/lib/ai/models.ts +1 -1
- package/templates/chat-app/lib/ai/providers.ts +10 -0
- package/templates/chat-app/lib/ai/text-splitter.ts +3 -4
- package/templates/chat-app/lib/ai/to-model-data.ts +1 -0
- package/templates/chat-app/lib/ai/tools/code-execution.ts +122 -53
- package/templates/chat-app/lib/ai/tools/deep-research/configuration.ts +35 -32
- package/templates/chat-app/lib/ai/tools/deep-research/pipeline.ts +2 -2
- package/templates/chat-app/lib/ai/tools/deep-research/types.ts +9 -9
- package/templates/chat-app/lib/ai/tools/documents/types.ts +4 -4
- package/templates/chat-app/lib/ai/tools/generate-image.ts +42 -20
- package/templates/chat-app/lib/ai/tools/generate-video.ts +166 -0
- package/templates/chat-app/lib/ai/tools/get-weather.ts +20 -20
- package/templates/chat-app/lib/ai/tools/read-document.ts +3 -3
- package/templates/chat-app/lib/ai/tools/steps/multi-query-web-search.ts +11 -11
- package/templates/chat-app/lib/ai/tools/steps/web-search.ts +6 -6
- package/templates/chat-app/lib/ai/tools/tools-definitions.ts +10 -5
- package/templates/chat-app/lib/ai/tools/tools.ts +15 -6
- package/templates/chat-app/lib/ai/tools/types.ts +2 -2
- package/templates/chat-app/lib/ai/types.ts +22 -13
- package/templates/chat-app/lib/artifacts/code/client.tsx +5 -5
- package/templates/chat-app/lib/artifacts/sheet/client.tsx +2 -2
- package/templates/chat-app/lib/artifacts/text/client.tsx +18 -3
- package/templates/chat-app/lib/clone-messages.test.ts +6 -1
- package/templates/chat-app/lib/config-requirements.ts +19 -10
- package/templates/chat-app/lib/config-schema.ts +189 -103
- package/templates/chat-app/lib/config.ts +4 -4
- package/templates/chat-app/lib/credits/cost-accumulator.ts +11 -8
- package/templates/chat-app/lib/env-schema.ts +1 -1
- package/templates/chat-app/lib/features-config.ts +6 -6
- package/templates/chat-app/lib/stores/with-threads.ts +3 -3
- package/templates/chat-app/lib/thread-utils.ts +2 -2
- package/templates/chat-app/lib/types/anonymous.ts +4 -4
- package/templates/chat-app/lib/types/ui-chat.ts +7 -7
- package/templates/chat-app/lib/utils/download-assets.ts +3 -3
- package/templates/chat-app/lib/utils/rate-limit.ts +8 -8
- package/templates/chat-app/next.config.ts +0 -25
- package/templates/chat-app/package.json +15 -15
- package/templates/chat-app/playwright.config.ts +5 -5
- package/templates/chat-app/providers/chat-id-provider.tsx +5 -5
- package/templates/chat-app/providers/chat-input-provider.tsx +15 -15
- package/templates/chat-app/providers/chat-models-provider.tsx +3 -3
- package/templates/chat-app/providers/default-model-provider.tsx +5 -5
- package/templates/chat-app/providers/parse-chat-id-from-pathname.test.ts +16 -0
- package/templates/chat-app/providers/session-provider.tsx +2 -2
- package/templates/chat-app/scripts/check-env.ts +36 -4
- package/templates/chat-app/tests/artifacts.e2e.ts +7 -0
- package/templates/chat-app/tests/auth.setup.e2e.ts +10 -0
- package/templates/chat-app/tests/chat.e2e.ts +7 -0
- package/templates/chat-app/tests/reasoning.e2e.ts +7 -0
- package/templates/chat-app/tests/reasoning.setup.e2e.ts +10 -0
- package/templates/chat-app/trpc/routers/chat.router.ts +1 -1
- package/templates/chat-app/trpc/routers/mcp.router.ts +3 -3
- package/templates/chat-app/vitest.config.ts +7 -0
|
@@ -62,8 +62,7 @@ export function ChatSync({
|
|
|
62
62
|
resume: isLastMessagePartial,
|
|
63
63
|
transport: new DefaultChatTransport({
|
|
64
64
|
api: "/api/chat",
|
|
65
|
-
|
|
66
|
-
fetch: fetchWithErrorHandlers,
|
|
65
|
+
fetch: fetchWithErrorHandlers as typeof fetch,
|
|
67
66
|
prepareSendMessagesRequest({ messages, id: requestId, body }) {
|
|
68
67
|
setAutoResume(true);
|
|
69
68
|
|
|
@@ -6,10 +6,10 @@ import { toast } from "sonner";
|
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
7
|
import { useCloneChat } from "@/hooks/chat-sync-hooks";
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
interface CloneChatButtonProps {
|
|
10
10
|
chatId: string;
|
|
11
11
|
className?: string;
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
|
|
14
14
|
export function CloneChatButton({ chatId, className }: CloneChatButtonProps) {
|
|
15
15
|
const router = useRouter();
|
|
@@ -8,15 +8,15 @@ import { EditorView } from "@codemirror/view";
|
|
|
8
8
|
import { basicSetup } from "codemirror";
|
|
9
9
|
import { memo, useEffect, useRef } from "react";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
interface EditorProps {
|
|
12
12
|
content: string;
|
|
13
|
-
onSaveContent: (updatedContent: string, debounce: boolean) => void;
|
|
14
|
-
status: "streaming" | "idle";
|
|
15
|
-
isCurrentVersion: boolean;
|
|
16
13
|
currentVersionIndex: number;
|
|
14
|
+
isCurrentVersion: boolean;
|
|
17
15
|
isReadonly?: boolean;
|
|
18
16
|
language?: string;
|
|
19
|
-
|
|
17
|
+
onSaveContent: (updatedContent: string, debounce: boolean) => void;
|
|
18
|
+
status: "streaming" | "idle";
|
|
19
|
+
}
|
|
20
20
|
|
|
21
21
|
function getLanguageExtension(language: string) {
|
|
22
22
|
switch (language) {
|
|
@@ -30,7 +30,7 @@ function PureConnectorsDropdown() {
|
|
|
30
30
|
|
|
31
31
|
const { data: connectors } = useQuery({
|
|
32
32
|
...trpc.mcp.listConnected.queryOptions(),
|
|
33
|
-
enabled: config.
|
|
33
|
+
enabled: config.ai.tools.mcp.enabled && isAuthenticated,
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
const queryKey = trpc.mcp.listConnected.queryKey();
|
|
@@ -59,7 +59,7 @@ function PureConnectorsDropdown() {
|
|
|
59
59
|
},
|
|
60
60
|
})
|
|
61
61
|
);
|
|
62
|
-
if (!config.
|
|
62
|
+
if (!config.ai.tools.mcp.enabled) {
|
|
63
63
|
return null;
|
|
64
64
|
}
|
|
65
65
|
if (!connectors || connectors.length === 0) {
|
|
@@ -4,16 +4,16 @@ import { useArtifactSelector } from "@/hooks/use-artifact";
|
|
|
4
4
|
import { cn } from "@/lib/utils";
|
|
5
5
|
import { Button } from "./ui/button";
|
|
6
6
|
|
|
7
|
-
export
|
|
7
|
+
export interface ConsoleOutputContent {
|
|
8
8
|
type: "text" | "image";
|
|
9
9
|
value: string;
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
export
|
|
12
|
+
export interface ConsoleOutput {
|
|
13
|
+
contents: ConsoleOutputContent[];
|
|
13
14
|
id: string;
|
|
14
15
|
status: "in_progress" | "loading_packages" | "completed" | "failed";
|
|
15
|
-
|
|
16
|
-
};
|
|
16
|
+
}
|
|
17
17
|
|
|
18
18
|
function getConsoleStatusText(consoleOutput: ConsoleOutput): string | null {
|
|
19
19
|
if (consoleOutput.status === "in_progress") {
|
|
@@ -7,59 +7,57 @@ import type { ChatMessage, CustomUIDataTypes } from "@/lib/ai/types";
|
|
|
7
7
|
import type { useTRPC } from "@/trpc/react";
|
|
8
8
|
import type { UIArtifact } from "./artifact-panel";
|
|
9
9
|
|
|
10
|
-
export
|
|
10
|
+
export interface ArtifactActionContext<M = any> {
|
|
11
11
|
content: string;
|
|
12
|
-
handleVersionChange: (type: "next" | "prev" | "toggle" | "latest") => void;
|
|
13
12
|
currentVersionIndex: number;
|
|
13
|
+
handleVersionChange: (type: "next" | "prev" | "toggle" | "latest") => void;
|
|
14
14
|
isCurrentVersion: boolean;
|
|
15
|
-
|
|
15
|
+
isReadonly?: boolean;
|
|
16
16
|
metadata: M;
|
|
17
|
+
mode: "edit" | "diff";
|
|
17
18
|
setMetadata: Dispatch<SetStateAction<M>>;
|
|
18
|
-
|
|
19
|
-
};
|
|
19
|
+
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
interface ArtifactAction<M = any> {
|
|
22
|
+
description: string;
|
|
22
23
|
icon: ReactNode;
|
|
24
|
+
isDisabled?: (context: ArtifactActionContext<M>) => boolean;
|
|
23
25
|
label?: string;
|
|
24
|
-
description: string;
|
|
25
26
|
onClick: (context: ArtifactActionContext<M>) => Promise<void> | void;
|
|
26
|
-
|
|
27
|
-
};
|
|
27
|
+
}
|
|
28
28
|
|
|
29
|
-
export
|
|
29
|
+
export interface ArtifactToolbarContext {
|
|
30
30
|
sendMessage: UseChatHelpers<ChatMessage>["sendMessage"];
|
|
31
31
|
storeApi: ReturnType<typeof useChatStoreApi<ChatMessage>>;
|
|
32
|
-
}
|
|
32
|
+
}
|
|
33
33
|
|
|
34
|
-
export
|
|
34
|
+
export interface ArtifactToolbarItem {
|
|
35
35
|
description: string;
|
|
36
36
|
icon: ReactNode;
|
|
37
37
|
onClick: (context: ArtifactToolbarContext) => void;
|
|
38
|
-
}
|
|
38
|
+
}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
title: string;
|
|
40
|
+
interface ArtifactContent<M = any> {
|
|
42
41
|
content: string;
|
|
43
|
-
mode: "edit" | "diff";
|
|
44
|
-
isCurrentVersion: boolean;
|
|
45
42
|
currentVersionIndex: number;
|
|
46
|
-
status: "streaming" | "idle";
|
|
47
|
-
onSaveContent: (updatedContent: string, debounce: boolean) => void;
|
|
48
|
-
isInline: boolean;
|
|
49
43
|
getDocumentContentById: (index: number) => string;
|
|
44
|
+
isCurrentVersion: boolean;
|
|
45
|
+
isInline: boolean;
|
|
50
46
|
isLoading: boolean;
|
|
47
|
+
isReadonly?: boolean;
|
|
51
48
|
metadata: M;
|
|
49
|
+
mode: "edit" | "diff";
|
|
50
|
+
onSaveContent: (updatedContent: string, debounce: boolean) => void;
|
|
52
51
|
setMetadata: Dispatch<SetStateAction<M>>;
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
status: "streaming" | "idle";
|
|
53
|
+
title: string;
|
|
54
|
+
}
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
description: string;
|
|
56
|
+
interface ArtifactConfig<T extends string, M = any> {
|
|
57
|
+
actions: ArtifactAction<M>[];
|
|
59
58
|
content: ComponentType<ArtifactContent<M>>;
|
|
59
|
+
description: string;
|
|
60
60
|
footer?: ComponentType<ArtifactContent<M>>;
|
|
61
|
-
actions: ArtifactAction<M>[];
|
|
62
|
-
toolbar: ArtifactToolbarItem[];
|
|
63
61
|
initialize?: ({
|
|
64
62
|
documentId,
|
|
65
63
|
setMetadata,
|
|
@@ -73,12 +71,14 @@ type ArtifactConfig<T extends string, M = any> = {
|
|
|
73
71
|
queryClient: QueryClient;
|
|
74
72
|
isAuthenticated: boolean;
|
|
75
73
|
}) => void;
|
|
74
|
+
kind: T;
|
|
76
75
|
onStreamPart?: (args: {
|
|
77
76
|
setMetadata: Dispatch<SetStateAction<M>>;
|
|
78
77
|
setArtifact: Dispatch<SetStateAction<UIArtifact>>;
|
|
79
78
|
streamPart: DataUIPart<CustomUIDataTypes>;
|
|
80
79
|
}) => void;
|
|
81
|
-
|
|
80
|
+
toolbar: ArtifactToolbarItem[];
|
|
81
|
+
}
|
|
82
82
|
|
|
83
83
|
export class Artifact<T extends string, M = any> {
|
|
84
84
|
readonly kind: T;
|
|
@@ -5,12 +5,12 @@ import type React from "react";
|
|
|
5
5
|
import { createContext, useContext, useMemo, useState } from "react";
|
|
6
6
|
import type { CustomUIDataTypes } from "@/lib/ai/types";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
interface DataStreamContextValue {
|
|
9
9
|
dataStream: DataUIPart<CustomUIDataTypes>[];
|
|
10
10
|
setDataStream: React.Dispatch<
|
|
11
11
|
React.SetStateAction<DataUIPart<CustomUIDataTypes>[]>
|
|
12
12
|
>;
|
|
13
|
-
}
|
|
13
|
+
}
|
|
14
14
|
|
|
15
15
|
const DataStreamContext = createContext<DataStreamContextValue | null>(null);
|
|
16
16
|
|
|
@@ -2,9 +2,9 @@ import { useMemo } from "react";
|
|
|
2
2
|
import type { ResearchUpdate } from "@/lib/ai/tools/research-updates-schema";
|
|
3
3
|
import { ResearchProgress } from "./research-progress";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
interface ReasonSearchResearchProgressProps {
|
|
6
6
|
updates: ResearchUpdate[];
|
|
7
|
-
}
|
|
7
|
+
}
|
|
8
8
|
|
|
9
9
|
export const ReasonSearchResearchProgress = ({
|
|
10
10
|
updates,
|
|
@@ -16,11 +16,11 @@ import {
|
|
|
16
16
|
import { useDeleteChat } from "@/hooks/chat-sync-hooks";
|
|
17
17
|
import { useChatId } from "@/providers/chat-id-provider";
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
interface DeleteChatDialogProps {
|
|
20
20
|
deleteId: string | null;
|
|
21
|
-
showDeleteDialog: boolean;
|
|
22
21
|
setShowDeleteDialog: (show: boolean) => void;
|
|
23
|
-
|
|
22
|
+
showDeleteDialog: boolean;
|
|
23
|
+
}
|
|
24
24
|
|
|
25
25
|
export function DeleteChatDialog({
|
|
26
26
|
deleteId,
|
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
} from "@/components/ui/alert-dialog";
|
|
18
18
|
import { useTRPC } from "@/trpc/react";
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
interface DeleteProjectDialogProps {
|
|
21
21
|
deleteId: string | null;
|
|
22
|
-
showDeleteDialog: boolean;
|
|
23
22
|
setShowDeleteDialog: (show: boolean) => void;
|
|
24
|
-
|
|
23
|
+
showDeleteDialog: boolean;
|
|
24
|
+
}
|
|
25
25
|
|
|
26
26
|
export function DeleteProjectDialog({
|
|
27
27
|
deleteId,
|
|
@@ -167,10 +167,10 @@ function DiffContentPlugin({
|
|
|
167
167
|
return null;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
|
|
171
|
-
oldContent: string;
|
|
170
|
+
interface DiffEditorProps {
|
|
172
171
|
newContent: string;
|
|
173
|
-
|
|
172
|
+
oldContent: string;
|
|
173
|
+
}
|
|
174
174
|
|
|
175
175
|
export const DiffView = ({ oldContent, newContent }: DiffEditorProps) => {
|
|
176
176
|
const initialConfig = {
|
|
@@ -3,16 +3,16 @@ import { cn } from "@/lib/utils";
|
|
|
3
3
|
import { Favicon } from "./favicon";
|
|
4
4
|
|
|
5
5
|
// Define a simpler interface for the sources needed by this component
|
|
6
|
-
|
|
7
|
-
url: string;
|
|
6
|
+
interface FaviconSource {
|
|
8
7
|
title?: string; // Title is optional, mainly for alt text
|
|
9
|
-
|
|
8
|
+
url: string;
|
|
9
|
+
}
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
sources: FaviconSource[]; // Use the simpler interface
|
|
13
|
-
maxVisible?: number;
|
|
11
|
+
interface FaviconGroupProps {
|
|
14
12
|
className?: string;
|
|
15
|
-
|
|
13
|
+
maxVisible?: number;
|
|
14
|
+
sources: FaviconSource[]; // Use the simpler interface
|
|
15
|
+
}
|
|
16
16
|
|
|
17
17
|
export const FaviconGroup: React.FC<FaviconGroupProps> = ({
|
|
18
18
|
sources,
|
|
@@ -32,14 +32,14 @@ import { cn } from "@/lib/utils";
|
|
|
32
32
|
import { useChatId } from "@/providers/chat-id-provider";
|
|
33
33
|
import { ShareDialog } from "./share-button";
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
interface HeaderBreadcrumbProps {
|
|
36
36
|
chatId: string;
|
|
37
|
+
className?: string;
|
|
38
|
+
hasMessages?: boolean;
|
|
39
|
+
isReadonly: boolean;
|
|
37
40
|
projectId?: string;
|
|
38
41
|
user?: Session["user"];
|
|
39
|
-
|
|
40
|
-
hasMessages?: boolean;
|
|
41
|
-
className?: string;
|
|
42
|
-
};
|
|
42
|
+
}
|
|
43
43
|
|
|
44
44
|
export function HeaderBreadcrumb({
|
|
45
45
|
chatId: _chatId,
|
|
@@ -181,7 +181,7 @@ export function HeaderBreadcrumb({
|
|
|
181
181
|
);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
|
|
184
|
+
interface ChatBreadcrumbProps {
|
|
185
185
|
canManageChat: boolean;
|
|
186
186
|
chatLabel: string;
|
|
187
187
|
chatTitleDraft: string;
|
|
@@ -195,7 +195,7 @@ type ChatBreadcrumbProps = {
|
|
|
195
195
|
openChatDeleteDialog: () => void;
|
|
196
196
|
showShare?: boolean;
|
|
197
197
|
startChatRename: () => void;
|
|
198
|
-
}
|
|
198
|
+
}
|
|
199
199
|
|
|
200
200
|
const PureChatBreadcrumb = memo(function InnerChatBreadcrumb({
|
|
201
201
|
canManageChat,
|
|
@@ -258,14 +258,14 @@ const PureChatBreadcrumb = memo(function InnerChatBreadcrumb({
|
|
|
258
258
|
return <BreadcrumbPage>{chatLabel}</BreadcrumbPage>;
|
|
259
259
|
});
|
|
260
260
|
|
|
261
|
-
|
|
261
|
+
interface PerformChatRenameArgs {
|
|
262
262
|
chatId: string;
|
|
263
263
|
chatTitleDraft: string;
|
|
264
264
|
privateChat: { title?: string; isPinned?: boolean } | null | undefined;
|
|
265
265
|
renameChat: (args: { chatId: string; title: string }) => Promise<unknown>;
|
|
266
266
|
setChatTitleDraft: (value: string) => void;
|
|
267
267
|
setIsChatEditing: (value: boolean) => void;
|
|
268
|
-
}
|
|
268
|
+
}
|
|
269
269
|
|
|
270
270
|
async function performChatRename({
|
|
271
271
|
chatId,
|
|
@@ -295,10 +295,10 @@ async function performChatRename({
|
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
interface InputKeyHandlerOptions {
|
|
299
299
|
onEnter: () => void;
|
|
300
300
|
onEscape: () => void;
|
|
301
|
-
}
|
|
301
|
+
}
|
|
302
302
|
|
|
303
303
|
function createInputKeyDownHandler({
|
|
304
304
|
onEnter,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Loader2 } from "lucide-react";
|
|
2
2
|
import { cn } from "@/lib/utils";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
title: string;
|
|
4
|
+
interface ImageEditorProps {
|
|
6
5
|
content: string;
|
|
7
|
-
isCurrentVersion: boolean;
|
|
8
6
|
currentVersionIndex: number;
|
|
9
|
-
|
|
7
|
+
isCurrentVersion: boolean;
|
|
10
8
|
isInline: boolean;
|
|
11
|
-
|
|
9
|
+
status: string;
|
|
10
|
+
title: string;
|
|
11
|
+
}
|
|
12
12
|
|
|
13
13
|
export function ImageEditor({
|
|
14
14
|
title,
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
} from "@/components/ui/dialog";
|
|
13
13
|
import { cn } from "@/lib/utils";
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
interface ImageModalProps {
|
|
16
|
+
imageName?: string;
|
|
17
|
+
imageUrl: string;
|
|
16
18
|
isOpen: boolean;
|
|
17
19
|
onClose: () => void;
|
|
18
|
-
imageUrl: string;
|
|
19
|
-
imageName?: string;
|
|
20
20
|
showActions?: boolean;
|
|
21
|
-
}
|
|
21
|
+
}
|
|
22
22
|
|
|
23
23
|
async function handleCopyImage(
|
|
24
24
|
e: React.MouseEvent,
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import ReactECharts from "echarts-for-react/lib/index";
|
|
4
|
+
import type { EChartsOption } from "echarts-for-react/lib/types";
|
|
5
|
+
import { motion } from "motion/react";
|
|
6
|
+
import { useTheme } from "next-themes";
|
|
7
|
+
import { Card } from "@/components/ui/card";
|
|
8
|
+
|
|
9
|
+
const CHART_COLORS = [
|
|
10
|
+
"#22c55e",
|
|
11
|
+
"#3b82f6",
|
|
12
|
+
"#f59e0b",
|
|
13
|
+
"#8b5cf6",
|
|
14
|
+
"#ec4899",
|
|
15
|
+
"#06b6d4",
|
|
16
|
+
"#ef4444",
|
|
17
|
+
"#84cc16",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
interface LineScatterElement {
|
|
21
|
+
label: string;
|
|
22
|
+
points: [number | string, number][];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface BarElement {
|
|
26
|
+
group: string;
|
|
27
|
+
label: string;
|
|
28
|
+
value: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface BaseChartCommon {
|
|
32
|
+
title: string;
|
|
33
|
+
x_label?: string;
|
|
34
|
+
y_label?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type LineChart = BaseChartCommon & {
|
|
38
|
+
type: "line";
|
|
39
|
+
x_scale?: "datetime";
|
|
40
|
+
elements: LineScatterElement[];
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type ScatterChart = BaseChartCommon & {
|
|
44
|
+
type: "scatter";
|
|
45
|
+
x_scale?: "datetime";
|
|
46
|
+
elements: LineScatterElement[];
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type BarChart = BaseChartCommon & {
|
|
50
|
+
type: "bar";
|
|
51
|
+
x_scale?: undefined;
|
|
52
|
+
elements: BarElement[];
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type BaseChart = LineChart | ScatterChart | BarChart;
|
|
56
|
+
|
|
57
|
+
function InteractiveChart({ chart }: { chart: BaseChart }) {
|
|
58
|
+
const { resolvedTheme } = useTheme();
|
|
59
|
+
const textColor = "#e5e5e5";
|
|
60
|
+
const gridColor = "rgba(255, 255, 255, 0.1)";
|
|
61
|
+
const tooltipBg = "#171717";
|
|
62
|
+
|
|
63
|
+
const sharedOptions: EChartsOption = {
|
|
64
|
+
backgroundColor: "transparent",
|
|
65
|
+
grid: {
|
|
66
|
+
top: 50,
|
|
67
|
+
right: 32,
|
|
68
|
+
bottom: 32,
|
|
69
|
+
left: 32,
|
|
70
|
+
containLabel: true,
|
|
71
|
+
},
|
|
72
|
+
legend: {
|
|
73
|
+
textStyle: { color: textColor },
|
|
74
|
+
top: 8,
|
|
75
|
+
icon: "circle",
|
|
76
|
+
itemWidth: 8,
|
|
77
|
+
itemHeight: 8,
|
|
78
|
+
itemGap: 16,
|
|
79
|
+
},
|
|
80
|
+
tooltip: {
|
|
81
|
+
trigger: "axis",
|
|
82
|
+
backgroundColor: tooltipBg,
|
|
83
|
+
borderWidth: 0,
|
|
84
|
+
padding: [6, 10],
|
|
85
|
+
className:
|
|
86
|
+
"echarts-tooltip rounded-lg! border! border-neutral-200! dark:border-neutral-800!",
|
|
87
|
+
textStyle: {
|
|
88
|
+
color: textColor,
|
|
89
|
+
fontSize: 13,
|
|
90
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const getChartOptions = (): EChartsOption => {
|
|
96
|
+
const defaultAxisOptions = {
|
|
97
|
+
axisLine: { show: true, lineStyle: { color: gridColor } },
|
|
98
|
+
axisTick: { show: false },
|
|
99
|
+
axisLabel: {
|
|
100
|
+
color: textColor,
|
|
101
|
+
margin: 8,
|
|
102
|
+
fontSize: 11,
|
|
103
|
+
hideOverlap: true,
|
|
104
|
+
},
|
|
105
|
+
nameTextStyle: {
|
|
106
|
+
color: textColor,
|
|
107
|
+
fontSize: 13,
|
|
108
|
+
padding: [0, 0, 0, 0],
|
|
109
|
+
},
|
|
110
|
+
splitLine: {
|
|
111
|
+
show: true,
|
|
112
|
+
lineStyle: { color: gridColor, type: "dashed" },
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
if (chart.type === "line" || chart.type === "scatter") {
|
|
117
|
+
const series = chart.elements.map((e, index) => ({
|
|
118
|
+
name: e.label,
|
|
119
|
+
type: chart.type,
|
|
120
|
+
data: e.points.map((p: [number | string, number]) => {
|
|
121
|
+
const x =
|
|
122
|
+
chart.x_scale === "datetime" ? new Date(p[0]).getTime() : p[0];
|
|
123
|
+
return [x, p[1]];
|
|
124
|
+
}),
|
|
125
|
+
smooth: true,
|
|
126
|
+
symbolSize: chart.type === "scatter" ? 10 : 0,
|
|
127
|
+
lineStyle: {
|
|
128
|
+
width: 2,
|
|
129
|
+
color: CHART_COLORS[index % CHART_COLORS.length],
|
|
130
|
+
},
|
|
131
|
+
itemStyle: {
|
|
132
|
+
color: CHART_COLORS[index % CHART_COLORS.length],
|
|
133
|
+
},
|
|
134
|
+
areaStyle:
|
|
135
|
+
chart.type === "line"
|
|
136
|
+
? {
|
|
137
|
+
color: {
|
|
138
|
+
type: "linear",
|
|
139
|
+
x: 0,
|
|
140
|
+
y: 0,
|
|
141
|
+
x2: 0,
|
|
142
|
+
y2: 1,
|
|
143
|
+
colorStops: [
|
|
144
|
+
{
|
|
145
|
+
offset: 0,
|
|
146
|
+
color: `${CHART_COLORS[index % CHART_COLORS.length]}15`,
|
|
147
|
+
},
|
|
148
|
+
{ offset: 1, color: "rgba(23, 23, 23, 0)" },
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
: undefined,
|
|
153
|
+
}));
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
...sharedOptions,
|
|
157
|
+
xAxis: {
|
|
158
|
+
type: chart.x_scale === "datetime" ? "time" : "value",
|
|
159
|
+
name: chart.x_label,
|
|
160
|
+
nameLocation: "middle",
|
|
161
|
+
nameGap: 40,
|
|
162
|
+
scale: true,
|
|
163
|
+
...defaultAxisOptions,
|
|
164
|
+
axisLabel: {
|
|
165
|
+
...defaultAxisOptions.axisLabel,
|
|
166
|
+
formatter:
|
|
167
|
+
chart.x_scale === "datetime"
|
|
168
|
+
? (value: number) => {
|
|
169
|
+
const date = new Date(value);
|
|
170
|
+
return date.toLocaleDateString("en-US", {
|
|
171
|
+
month: "short",
|
|
172
|
+
year: "numeric",
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
: undefined,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
yAxis: {
|
|
179
|
+
type: "value",
|
|
180
|
+
name: chart.y_label,
|
|
181
|
+
nameLocation: "middle",
|
|
182
|
+
nameGap: 50,
|
|
183
|
+
position: "right",
|
|
184
|
+
scale: true,
|
|
185
|
+
...defaultAxisOptions,
|
|
186
|
+
},
|
|
187
|
+
series,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (chart.type === "bar") {
|
|
192
|
+
const data = chart.elements.reduce(
|
|
193
|
+
(acc: Record<string, BarElement[]>, item) => {
|
|
194
|
+
const key = item.group;
|
|
195
|
+
if (!acc[key]) {
|
|
196
|
+
acc[key] = [];
|
|
197
|
+
}
|
|
198
|
+
acc[key].push(item);
|
|
199
|
+
return acc;
|
|
200
|
+
},
|
|
201
|
+
{}
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
const series = Object.entries(data).map(([group, elements], index) => ({
|
|
205
|
+
name: group,
|
|
206
|
+
type: "bar",
|
|
207
|
+
stack: "total",
|
|
208
|
+
data: elements?.map((e) => [e.label, e.value]),
|
|
209
|
+
itemStyle: {
|
|
210
|
+
color: CHART_COLORS[index % CHART_COLORS.length],
|
|
211
|
+
},
|
|
212
|
+
emphasis: {
|
|
213
|
+
itemStyle: {
|
|
214
|
+
shadowBlur: 10,
|
|
215
|
+
shadowColor: "rgba(0,0,0,0.3)",
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
}));
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
...sharedOptions,
|
|
222
|
+
xAxis: {
|
|
223
|
+
type: "category",
|
|
224
|
+
name: chart.x_label,
|
|
225
|
+
nameLocation: "middle",
|
|
226
|
+
nameGap: 40,
|
|
227
|
+
...defaultAxisOptions,
|
|
228
|
+
},
|
|
229
|
+
yAxis: {
|
|
230
|
+
type: "value",
|
|
231
|
+
name: chart.y_label,
|
|
232
|
+
nameLocation: "middle",
|
|
233
|
+
nameGap: 50,
|
|
234
|
+
position: "right",
|
|
235
|
+
...defaultAxisOptions,
|
|
236
|
+
},
|
|
237
|
+
series,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return sharedOptions;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
return (
|
|
245
|
+
<motion.div
|
|
246
|
+
animate={{ opacity: 1, y: 0 }}
|
|
247
|
+
initial={{ opacity: 0, y: 20 }}
|
|
248
|
+
transition={{ duration: 0.5 }}
|
|
249
|
+
>
|
|
250
|
+
<Card className="overflow-hidden border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900">
|
|
251
|
+
<div className="p-6">
|
|
252
|
+
{chart.title && (
|
|
253
|
+
<h3 className="mb-4 font-medium text-lg text-neutral-900 dark:text-neutral-100">
|
|
254
|
+
{chart.title}
|
|
255
|
+
</h3>
|
|
256
|
+
)}
|
|
257
|
+
<ReactECharts
|
|
258
|
+
notMerge={true}
|
|
259
|
+
option={getChartOptions()}
|
|
260
|
+
style={{ height: "400px", width: "100%" }}
|
|
261
|
+
theme={resolvedTheme === "dark" ? "dark" : undefined}
|
|
262
|
+
/>
|
|
263
|
+
</div>
|
|
264
|
+
</Card>
|
|
265
|
+
</motion.div>
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export default InteractiveChart;
|