Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions app/api/generate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ function isGenerateProps(value: unknown): value is GenerateProps {
if (!value || typeof value !== 'object') return false

const body = value as Partial<GenerateProps>
const validChatMode = body.chatMode === undefined
|| body.chatMode === 'general'
|| body.chatMode === 'learn'
|| body.chatMode === 'research'
|| body.chatMode === 'build'

return typeof body.prompt === 'string'
&& typeof body.tool === 'string'
Expand All @@ -29,7 +24,6 @@ function isGenerateProps(value: unknown): value is GenerateProps {
&& (body.sessionId === undefined || body.sessionId === null || typeof body.sessionId === 'string')
&& (body.chatId === undefined || typeof body.chatId === 'string')
&& (body.researchMode === undefined || typeof body.researchMode === 'boolean')
&& validChatMode
&& (body.chatMode === undefined || isChatMode(body.chatMode))
&& (body.attachments === undefined || Array.isArray(body.attachments))
}
Expand All @@ -55,19 +49,8 @@ export async function POST(request: Request) {
}, { status: 400 })
}

try {
return NextResponse.json(await generateAnswerForPrompt(body))
const chatMode = normalizeChatMode(body.chatMode)

if (!chatMode) {
return NextResponse.json<GenerateErrorResponse>({
answer: 'Invalid message request.',
sessionId: body.sessionId ?? null,
chatId: body.chatId,
error: 'Invalid message request.',
}, { status: 400 })
}

if (chatMode === 'image') {
const message = 'Image creation is coming soon.'
return NextResponse.json<GenerateErrorResponse>({
Expand Down
14 changes: 6 additions & 8 deletions components/PromptShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import React, { ChangeEvent, useCallback, useEffect, useRef, useState, useTransition } from 'react'
import Image from 'next/image'
import type { GenerateAnswerResult, GenerateProps, TeraChatMode } from '@/lib/generate-types'
import type { GenerateAnswerResult, GenerateProps } from '@/lib/generate-types'
import { CHAT_MODES, getChatModeConfig, isChatMode, type ChatMode } from '@/lib/chat-modes'
import type { TeacherTool } from './ToolCard'
Expand All @@ -18,7 +17,6 @@ import { fetchChatHistory } from '@/app/actions/user'
import { addNote } from '@/app/actions/notes'
import { dispatchUsageRefresh } from '@/lib/usage-events'
import { compressImage } from '@/lib/image-compression'
import { getChatModeConfig, isChatMode, type ChatMode } from '@/lib/ai/chat-modes'
import UpgradePrompt from './UpgradePrompt'
import VoiceControls from './VoiceControls'
import LimitModal from './LimitModal'
Expand Down Expand Up @@ -53,7 +51,7 @@ type QueuedMessage = {

const createId = () => (crypto.randomUUID ? crypto.randomUUID() : String(Date.now()))

const inferChatMode = (tool: TeacherTool, researchMode: boolean): TeraChatMode => {
const inferChatMode = (tool: TeacherTool, researchMode: boolean) => {
if (researchMode) return 'research'

const searchable = `${tool.name} ${tool.description} ${tool.tags.join(' ')}`.toLowerCase()
Expand All @@ -71,6 +69,8 @@ const inferChatMode = (tool: TeacherTool, researchMode: boolean): TeraChatMode =
}

return 'general'
}

const getChatModeForTool = (toolName: string): ChatMode => {
const normalized = toolName.toLowerCase()

Expand Down Expand Up @@ -434,7 +434,6 @@ export default function PromptShell({
sessionId: currentSessionId,
chatId: editingMessageId ?? undefined,
researchMode,
chatMode: inferChatMode(tool, researchMode)
chatMode: outgoingChatMode,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Send backend chatMode enum instead of UI mode values

processMessage now always sends chatMode: outgoingChatMode, which is a UI mode (ask/study/image) rather than the API enum expected by POST /api/generate. In app/api/generate/route.ts, isGenerateProps only accepts general|learn|research|build for body.chatMode, so requests from this component are rejected as 400 Invalid message request whenever chatMode is present. This regression was introduced when the inferChatMode(...) field was removed from the payload, so normal chat submissions can fail before generation runs.

Useful? React with 👍 / 👎.

})

Expand Down Expand Up @@ -464,7 +463,6 @@ export default function PromptShell({
setQueuedMessage(null)
})
}, [editingMessageId, hasBumpedInput, tool, user?.id, user?.email, currentSessionId, researchMode])
}, [editingMessageId, hasBumpedInput, tool.name, user?.id, user?.email, currentSessionId, researchMode])

const handleSaveNote = async (assistantMessage: Message) => {
if (!user?.id) {
Expand Down Expand Up @@ -562,12 +560,12 @@ export default function PromptShell({
fetchChatHistory(user.id, sessionId).then(data => {
if (data) {
const loaded: ConversationEntry[] = data.map(s => {
const chatMode = getChatModeForTool(s.tool ?? tool.name)
const mode = getChatModeForTool(s.tool ?? tool.name)

return {
id: s.id, sessionId: s.id,
userMessage: { id: `${s.id}-user`, role: 'user', content: s.prompt, attachments: s.attachments as AttachmentReference[], timestamp: new Date(s.created_at).getTime(), chatMode },
assistantMessage: { id: `${s.id}-assistant`, role: 'tera', content: s.response, timestamp: new Date(s.created_at).getTime() + 1000, chatMode }
userMessage: { id: `${s.id}-user`, role: 'user', content: s.prompt, attachments: s.attachments as AttachmentReference[], timestamp: new Date(s.created_at).getTime(), chatMode: mode },
assistantMessage: { id: `${s.id}-assistant`, role: 'tera', content: s.response, timestamp: new Date(s.created_at).getTime() + 1000, chatMode: mode }
}
})
setConversations(prev => loaded.length === 0 && prev.length > 0 ? prev : loaded)
Expand Down
4 changes: 0 additions & 4 deletions lib/generate-answer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ function omitField<T extends Record<string, any>, K extends keyof T>(payload: T,
return rest
}

export async function generateAnswerForPrompt({ prompt, tool, authorId, authorEmail, attachments = [], sessionId, chatId, researchMode = false, chatMode = researchMode ? 'research' : 'general' }: GenerateProps): Promise<GenerateAnswerResult> {
// Get user profile and check limits
export async function generateAnswerForPrompt({
prompt,
tool,
Expand Down Expand Up @@ -126,7 +124,6 @@ export async function generateAnswerForPrompt({
chatId: chatId ?? null,
resetDate,
promptLength: prompt.length,
chatMode,
chatMode: normalizedChatMode,
},
})
Expand Down Expand Up @@ -180,7 +177,6 @@ export async function generateAnswerForPrompt({
}

// Generate the AI response
const generationResult = await generateTeacherResponse({ prompt, tool, attachments, history, userId: authorId, researchMode, chatMode })
const generationResult = await generateTeacherResponse({
prompt,
tool,
Expand Down
3 changes: 0 additions & 3 deletions lib/generate-types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import type { AttachmentReference } from '@/lib/attachment'

export type TeraChatMode = 'general' | 'learn' | 'research' | 'build'
import type { ChatMode } from '@/lib/ai/chat-modes'

export type GenerateProps = {
Expand All @@ -12,7 +10,6 @@ export type GenerateProps = {
sessionId?: string | null
chatId?: string
researchMode?: boolean
chatMode?: TeraChatMode
chatMode?: ChatMode
}

Expand Down