@chat-js/cli 0.3.0 → 0.4.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 +11 -6
- package/package.json +1 -1
- package/templates/chat-app/app/(chat)/api/chat/prepare/route.ts +94 -0
- package/templates/chat-app/app/(chat)/api/chat/route.ts +97 -14
- package/templates/chat-app/chat.config.ts +141 -124
- package/templates/chat-app/components/chat-sync.tsx +6 -3
- package/templates/chat-app/components/feedback-actions.tsx +7 -3
- package/templates/chat-app/components/message-editor.tsx +8 -3
- package/templates/chat-app/components/message-siblings.tsx +14 -1
- package/templates/chat-app/components/model-selector.tsx +669 -407
- package/templates/chat-app/components/multimodal-input.tsx +252 -18
- package/templates/chat-app/components/parallel-response-cards.tsx +157 -0
- package/templates/chat-app/components/part/text-message-part.tsx +9 -5
- package/templates/chat-app/components/retry-button.tsx +25 -8
- package/templates/chat-app/components/user-message.tsx +136 -125
- package/templates/chat-app/hooks/chat-sync-hooks.ts +11 -0
- package/templates/chat-app/hooks/use-navigate-to-message.ts +39 -0
- package/templates/chat-app/lib/ai/types.ts +74 -3
- package/templates/chat-app/lib/config-schema.ts +5 -0
- package/templates/chat-app/lib/db/migrations/0044_gray_red_shift.sql +5 -0
- package/templates/chat-app/lib/db/migrations/meta/0044_snapshot.json +1567 -0
- package/templates/chat-app/lib/db/migrations/meta/_journal.json +8 -1
- package/templates/chat-app/lib/db/queries.ts +84 -4
- package/templates/chat-app/lib/db/schema.ts +4 -1
- package/templates/chat-app/lib/message-conversion.ts +14 -2
- package/templates/chat-app/lib/stores/hooks-threads.ts +37 -1
- package/templates/chat-app/lib/stores/with-threads.test.ts +137 -0
- package/templates/chat-app/lib/stores/with-threads.ts +157 -4
- package/templates/chat-app/lib/thread-utils.ts +23 -2
- package/templates/chat-app/providers/chat-input-provider.tsx +40 -2
- package/templates/chat-app/scripts/db-branch-delete.sh +7 -1
- package/templates/chat-app/scripts/db-branch-use.sh +7 -1
- package/templates/chat-app/scripts/with-db.sh +7 -1
- package/templates/chat-app/vitest.config.ts +2 -0
|
@@ -13,7 +13,12 @@ import React, {
|
|
|
13
13
|
} from "react";
|
|
14
14
|
import type { LexicalChatInputRef } from "@/components/lexical-chat-input";
|
|
15
15
|
import type { AppModelId } from "@/lib/ai/app-models";
|
|
16
|
-
import
|
|
16
|
+
import {
|
|
17
|
+
getPrimarySelectedModelId,
|
|
18
|
+
type Attachment,
|
|
19
|
+
type SelectedModelValue,
|
|
20
|
+
type UiToolName,
|
|
21
|
+
} from "@/lib/ai/types";
|
|
17
22
|
import { useChatModels } from "./chat-models-provider";
|
|
18
23
|
import { useDefaultModel, useModelChange } from "./default-model-provider";
|
|
19
24
|
|
|
@@ -24,10 +29,12 @@ interface ChatInputContextType {
|
|
|
24
29
|
getInputValue: () => string;
|
|
25
30
|
handleInputChange: (value: string) => void;
|
|
26
31
|
handleModelChange: (modelId: AppModelId) => Promise<void>;
|
|
32
|
+
handleModelSelectionChange: (selection: SelectedModelValue) => Promise<void>;
|
|
27
33
|
handleSubmit: (submitFn: () => void, isEditMode?: boolean) => void;
|
|
28
34
|
isEmpty: boolean;
|
|
29
35
|
isProjectContext: boolean;
|
|
30
36
|
selectedModelId: AppModelId;
|
|
37
|
+
selectedModelSelection: SelectedModelValue;
|
|
31
38
|
selectedTool: UiToolName | null;
|
|
32
39
|
setAttachments: Dispatch<SetStateAction<Attachment[]>>;
|
|
33
40
|
setSelectedTool: Dispatch<SetStateAction<UiToolName | null>>;
|
|
@@ -45,6 +52,7 @@ interface ChatInputProviderProps {
|
|
|
45
52
|
isProjectContext?: boolean;
|
|
46
53
|
localStorageEnabled?: boolean;
|
|
47
54
|
overrideModelId?: AppModelId; // For message editing where we want to use the original model
|
|
55
|
+
overrideModelSelection?: SelectedModelValue; // For message editing with multi-model selection
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
export function ChatInputProvider({
|
|
@@ -53,6 +61,7 @@ export function ChatInputProvider({
|
|
|
53
61
|
initialTool = null,
|
|
54
62
|
initialAttachments = [],
|
|
55
63
|
overrideModelId,
|
|
64
|
+
overrideModelSelection,
|
|
56
65
|
localStorageEnabled = true,
|
|
57
66
|
isProjectContext = false,
|
|
58
67
|
}: ChatInputProviderProps) {
|
|
@@ -95,6 +104,10 @@ export function ChatInputProvider({
|
|
|
95
104
|
const [selectedModelId, setSelectedModelId] = useState<AppModelId>(
|
|
96
105
|
overrideModelId || defaultModel
|
|
97
106
|
);
|
|
107
|
+
const [selectedModelSelection, setSelectedModelSelection] =
|
|
108
|
+
useState<SelectedModelValue>(
|
|
109
|
+
overrideModelSelection ?? overrideModelId ?? defaultModel
|
|
110
|
+
);
|
|
98
111
|
|
|
99
112
|
// IMPORTANT: do not read localStorage during initial render.
|
|
100
113
|
// Next SSRs client components; localStorage is client-only and will cause hydration mismatches
|
|
@@ -128,7 +141,7 @@ export function ChatInputProvider({
|
|
|
128
141
|
|
|
129
142
|
const { getModelById } = useChatModels();
|
|
130
143
|
|
|
131
|
-
const
|
|
144
|
+
const persistPrimaryModelChange = useCallback(
|
|
132
145
|
async (modelId: AppModelId) => {
|
|
133
146
|
const modelDef = getModelById(modelId);
|
|
134
147
|
|
|
@@ -146,6 +159,29 @@ export function ChatInputProvider({
|
|
|
146
159
|
[selectedTool, changeModel, getModelById]
|
|
147
160
|
);
|
|
148
161
|
|
|
162
|
+
const handleModelChange = useCallback(
|
|
163
|
+
async (modelId: AppModelId) => {
|
|
164
|
+
setSelectedModelSelection(modelId);
|
|
165
|
+
await persistPrimaryModelChange(modelId);
|
|
166
|
+
},
|
|
167
|
+
[persistPrimaryModelChange]
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const handleModelSelectionChange = useCallback(
|
|
171
|
+
async (selection: SelectedModelValue) => {
|
|
172
|
+
setSelectedModelSelection(selection);
|
|
173
|
+
|
|
174
|
+
const primaryModelId = getPrimarySelectedModelId(selection);
|
|
175
|
+
|
|
176
|
+
if (!primaryModelId) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
await persistPrimaryModelChange(primaryModelId);
|
|
181
|
+
},
|
|
182
|
+
[persistPrimaryModelChange]
|
|
183
|
+
);
|
|
184
|
+
|
|
149
185
|
const clearInput = useCallback(() => {
|
|
150
186
|
editorRef.current?.clear();
|
|
151
187
|
setLocalStorageInput("");
|
|
@@ -207,7 +243,9 @@ export function ChatInputProvider({
|
|
|
207
243
|
attachments,
|
|
208
244
|
setAttachments,
|
|
209
245
|
selectedModelId,
|
|
246
|
+
selectedModelSelection,
|
|
210
247
|
handleModelChange,
|
|
248
|
+
handleModelSelectionChange,
|
|
211
249
|
getInputValue,
|
|
212
250
|
handleInputChange,
|
|
213
251
|
getInitialInput,
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
set -e
|
|
3
3
|
|
|
4
4
|
BRANCH_NAME="${1:-dev-local}"
|
|
5
|
-
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
MONOREPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
|
7
|
+
if [ -f "$MONOREPO_ROOT/turbo.json" ]; then
|
|
8
|
+
BRANCH_FILE="$MONOREPO_ROOT/.neon-branch"
|
|
9
|
+
else
|
|
10
|
+
BRANCH_FILE="$(cd "$SCRIPT_DIR/.." && pwd)/.neon-branch"
|
|
11
|
+
fi
|
|
6
12
|
|
|
7
13
|
# Check if we're currently on this branch
|
|
8
14
|
if [ -f "$BRANCH_FILE" ] && [ "$(cat "$BRANCH_FILE")" = "$BRANCH_NAME" ]; then
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
# Switch active database branch (like git checkout)
|
|
3
3
|
set -e
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
MONOREPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
|
7
|
+
if [ -f "$MONOREPO_ROOT/turbo.json" ]; then
|
|
8
|
+
BRANCH_FILE="$MONOREPO_ROOT/.neon-branch"
|
|
9
|
+
else
|
|
10
|
+
BRANCH_FILE="$(cd "$SCRIPT_DIR/.." && pwd)/.neon-branch"
|
|
11
|
+
fi
|
|
6
12
|
BRANCH_NAME="${1:-}"
|
|
7
13
|
|
|
8
14
|
if [ -z "$BRANCH_NAME" ]; then
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
# Wrapper that uses branch DATABASE_URL if .neon-branch exists, otherwise uses .env.local
|
|
3
3
|
set -e
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
MONOREPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
|
7
|
+
if [ -f "$MONOREPO_ROOT/turbo.json" ]; then
|
|
8
|
+
BRANCH_FILE="$MONOREPO_ROOT/.neon-branch"
|
|
9
|
+
else
|
|
10
|
+
BRANCH_FILE="$(cd "$SCRIPT_DIR/.." && pwd)/.neon-branch"
|
|
11
|
+
fi
|
|
6
12
|
|
|
7
13
|
if [ -f "$BRANCH_FILE" ]; then
|
|
8
14
|
BRANCH_NAME=$(cat "$BRANCH_FILE")
|