Skip to content

Commit 08163cd

Browse files
committed
fix: handle case when no csv file selected
1 parent f3eef14 commit 08163cd

File tree

5 files changed

+73
-6
lines changed

5 files changed

+73
-6
lines changed

apps/postgres-new/app/api/chat/route.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ export async function POST(req: Request) {
4141
When querying data, limit to 5 by default.
4242
4343
When performing FTS, always use 'simple' (languages aren't available).
44+
45+
When importing CSVs try to solve the problem yourself (eg. use a generic text column, then refine)
46+
vs. asking the user to change the CSV.
4447
4548
You also know math. All math equations and expressions must be written in KaTex and must be wrapped in double dollar \`$$\`:
4649
- Inline: $$\\sqrt{26}$$

apps/postgres-new/components/chat.tsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,28 @@ export default function Chat() {
7373

7474
const sendCsv = useCallback(
7575
async (file: File) => {
76+
if (file.type !== 'text/csv') {
77+
// Add an artificial tool call requesting the CSV
78+
// with an error indicating the file wasn't a CSV
79+
appendMessage({
80+
role: 'assistant',
81+
content: '',
82+
toolInvocations: [
83+
{
84+
state: 'result',
85+
toolCallId: generateId(),
86+
toolName: 'requestCsv',
87+
args: {},
88+
result: {
89+
success: false,
90+
error: `The file has type '${file.type}'. Let the user know that only CSV imports are currently supported.`,
91+
},
92+
},
93+
],
94+
})
95+
return
96+
}
97+
7698
const fileId = generateId()
7799

78100
await saveFile(fileId, file)
@@ -120,7 +142,7 @@ export default function Chat() {
120142

121143
const [file] = files
122144

123-
if (file && file.type === 'text/csv') {
145+
if (file) {
124146
await sendCsv(file)
125147
}
126148
},
@@ -402,7 +424,7 @@ export default function Chat() {
402424
const changeEvent = event as unknown as ChangeEvent<HTMLInputElement>
403425
const [file] = Array.from(changeEvent.target?.files ?? [])
404426

405-
if (file && file.type === 'text/csv') {
427+
if (file) {
406428
await sendCsv(file)
407429
}
408430

apps/postgres-new/components/tools/csv-request.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,20 @@ export default function CsvRequest({ toolInvocation }: CsvRequestProps) {
2323
const { result } = toolInvocation
2424

2525
if (!result.success) {
26-
return null
26+
return (
27+
<m.div
28+
layout="position"
29+
layoutId={toolInvocation.toolCallId}
30+
className="self-end px-5 py-2.5 text-base rounded-full bg-destructive flex gap-2 items-center text-lighter italic"
31+
>
32+
No CSV file selected
33+
</m.div>
34+
)
2735
}
2836

2937
return (
3038
<m.div
39+
layout="position"
3140
layoutId={toolInvocation.toolCallId}
3241
className="self-end px-5 py-2.5 text-base rounded-full bg-border flex gap-2 items-center text-lighter italic"
3342
style={{
@@ -52,7 +61,7 @@ export default function CsvRequest({ toolInvocation }: CsvRequestProps) {
5261
}
5362

5463
return (
55-
<m.div layoutId={toolInvocation.toolCallId}>
64+
<m.div layout="position" layoutId={toolInvocation.toolCallId}>
5665
<input
5766
type="file"
5867
onChange={async (e) => {

apps/postgres-new/components/workspace.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { useMessagesQuery } from '~/data/messages/messages-query'
77
import { useTablesQuery } from '~/data/tables/tables-query'
88
import { useOnToolCall } from '~/lib/hooks'
99
import { useBreakpoint } from '~/lib/use-breakpoint'
10-
import { ensureMessageId } from '~/lib/util'
10+
import { ensureMessageId, ensureToolResult } from '~/lib/util'
1111
import { useApp } from './app-provider'
1212
import Chat, { getInitialMessages } from './chat'
1313
import IDE from './ide'
@@ -48,6 +48,7 @@ export default function Workspace({ databaseId, visibility, onStart }: Workspace
4848

4949
const {
5050
messages,
51+
setMessages,
5152
append,
5253
stop: stopReply,
5354
} = useChat({
@@ -84,11 +85,15 @@ export default function Workspace({ databaseId, visibility, onStart }: Workspace
8485

8586
const appendMessage = useCallback(
8687
async (message: Message | CreateMessage) => {
88+
setMessages((messages) => {
89+
const isModified = ensureToolResult(messages)
90+
return isModified ? [...messages] : messages
91+
})
8792
ensureMessageId(message)
8893
append(message)
8994
saveMessage({ message })
9095
},
91-
[saveMessage, append]
96+
[setMessages, saveMessage, append]
9297
)
9398

9499
const isConversationStarted =

apps/postgres-new/lib/util.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,34 @@ export function ensureMessageId(message: Message | CreateMessage): asserts messa
2323
}
2424
}
2525

26+
/**
27+
* Ensures that all tool invocations have a result before submitting,
28+
* otherwise the LLM provider will return an error.
29+
*/
30+
export function ensureToolResult(messages: Message[]) {
31+
let modified = false
32+
33+
for (const message of messages) {
34+
if (!message.toolInvocations) {
35+
continue
36+
}
37+
38+
for (const toolInvocation of message.toolInvocations) {
39+
if (!('result' in toolInvocation)) {
40+
Object.assign(toolInvocation, {
41+
result: {
42+
success: false,
43+
error: 'Failed to complete',
44+
},
45+
})
46+
modified = true
47+
}
48+
}
49+
}
50+
51+
return modified
52+
}
53+
2654
/**
2755
* Checks if the message is a user message sent by the
2856
* application instead of the user.

0 commit comments

Comments
 (0)