Skip to content
Open
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
1,237 changes: 1,237 additions & 0 deletions Phase_0_Chat_Refactor.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ tasks:
# [AFTER applying metadata & migrations] Apply the hasura seeds
seed:
cmds:
- hasura seeds apply --project apps/hasura --admin-secret ${HASURA_GRAPHQL_ADMIN_SECRET}
- hasura seeds apply --project apps/hasura --admin-secret ${HASURA_GRAPHQL_ADMIN_SECRET} --database-name masterbots

# Turns on the hasura backend (docker desktop must be started first)
up:
Expand Down
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
3 changes: 0 additions & 3 deletions apps/pro-web/app/actions/admin.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ export async function insertAdminUserPreferences({
userId: string
preferencesSet: PgInsertValue<typeof preference>
}) {
await verifyUserExists(userId)
return await db
.insert(preference)
.values({ ...preferencesSet })
Expand All @@ -141,8 +140,6 @@ export async function insertUserOrganizations({
}>
}>
}) {
await verifyUserExists(userId)

if (!organizationsList || organizationsList.length === 0) {
return []
}
Expand Down
53 changes: 37 additions & 16 deletions apps/pro-web/app/actions/chat-memory/ingest-assistant-answer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,43 @@ export async function ingestAssistantAnswer(
const nextTurnIndex = (lastEntry?.turnIndex ?? 0) + 1

// 5) insert (idempotent by message_id)
await db
.insert(assistantAnswers)
.values({
content,
scopeId,
threadId,
docNodeId,
embedding, // Pass raw number[] array, Drizzle/pg handles vector formatting
messageId,
contentHash,
turnIndex: nextTurnIndex,
scopeType: (scopeType || 'chat_thread') as ScopeType, // Default to chat_thread if undefined
})
.onConflictDoNothing({
target: assistantAnswers.messageId,
})
const MAX_RETRIES = 5
const baseDelay = 1000

for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
try {
await db
.insert(assistantAnswers)
.values({
content,
scopeId,
threadId,
docNodeId,
embedding, // Pass raw number[] array, Drizzle/pg handles vector formatting
messageId,
contentHash,
turnIndex: nextTurnIndex,
scopeType: (scopeType || 'chat_thread') as ScopeType, // Default to chat_thread if undefined
})
.onConflictDoNothing({
target: assistantAnswers.messageId,
})
break // Success, exit loop
} catch (error) {
const pgError = error as { code?: string }
// Check for Foreign Key Violation (Postgres code 23503)
// This implies the thread_id doesn't exist yet (race condition)
if (pgError?.code === '23503' && attempt < MAX_RETRIES) {
const delay = baseDelay * 2 ** (attempt - 1)
console.warn(
`[ingestAssistantAnswer] FK violation on attempt ${attempt}. Retrying in ${delay}ms...`,
)
await new Promise((resolve) => setTimeout(resolve, delay))
continue
}
throw error // Re-throw if not FK error or retries exhausted
}
}

// Log success
// console.log(`[ingestAssistantAnswer] Ingested message ${messageId} (turn ${nextTurnIndex})`)
Expand Down
30 changes: 13 additions & 17 deletions apps/pro-web/app/actions/subscriptions.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,23 +188,19 @@ export async function getPromptDetails(promptId: string) {
throw new Error(data.error || 'Failed to fetch prompt details')
}

inputs = (
data.inputs as {
label: string
type: string
required: boolean
default: string
options: string[]
pattern: string
min_length: number
max_length: number
}[]
).reduce(
(acc, input) => ({
...acc,
[input.label]: '',
}),
{},
inputs = Object.fromEntries(
(
data.inputs as {
label: string
type: string
required: boolean
default: string
options: string[]
pattern: string
min_length: number
max_length: number
}[]
).map((input) => [input.label, '']),
)
} catch (err) {
console.error('Error fetching prompt details:', error)
Comment on lines 205 to 206
Copy link

Choose a reason for hiding this comment

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

issue (bug_risk): The catch block logs an undefined error variable instead of the caught err.

In this catch block, err is the caught exception, but console.error references error, which is undefined in this scope and will throw a ReferenceError, masking the real issue. Use err in the log call instead.

Expand Down
18 changes: 17 additions & 1 deletion apps/pro-web/app/actions/thread.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,23 @@ export async function uploadWorkspaceDocumentToBucket({
type?: WorkspaceDocumentType
}) {
if (!content) throw new Error('Document content required')
const existingThread = await getThreadBySlug(threadSlug)

let existingThread = null
const MAX_RETRIES = 5
const baseDelay = 1000

for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
existingThread = await getThreadBySlug(threadSlug)
if (existingThread) break
if (attempt < MAX_RETRIES) {
const delay = baseDelay * 2 ** (attempt - 1)
console.warn(
`[uploadWorkspaceDocumentToBucket] Thread not found for slug ${threadSlug} on attempt ${attempt}. Retrying in ${delay}ms...`,
)
await new Promise((resolve) => setTimeout(resolve, delay))
}
}

if (!existingThread) throw new Error('Thread not found for slug')
const existingDocs: WorkspaceDocumentMetadata[] =
(existingThread.metadata as ThreadMetadata | null)?.documents || []
Expand Down
21 changes: 12 additions & 9 deletions apps/pro-web/app/api/auth/signup/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import crypto from 'node:crypto'
import {
insertAdminUserPreferences,
insertUserOrganizations,
} from '@/app/actions/admin.actions'
import { insertUserOrganizations } from '@/app/actions/admin.actions'
import { sendEmailVerification } from '@/lib/email'
import { generateUsername } from '@/lib/username'
import { delayFetch } from '@/lib/utils'
import { isUsernameTaken } from '@/services/hasura/hasura.service'
import {
insertPreferencesByUserId,
isUsernameTaken,
} from '@/services/hasura/hasura.service'
import type { OrganizationData } from '@/types/thread.types'
import bcryptjs from 'bcryptjs'
import { appConfig } from 'mb-env'
Expand Down Expand Up @@ -126,10 +126,13 @@ export async function POST(req: NextRequest) {
)
}

const insertPreferenceResults = await insertAdminUserPreferences({
userId: insertUserOne.userId,
const { data: preference, error } = await insertPreferencesByUserId({
// userId is not needed in the object for this specific function signature in hasura.service,
// check the definition of insertPreferencesByUserId manually?
// Wait, let me check the signature of insertPreferencesByUserId again.
// It takes { jwt, preferencesSet }. preferencesSet is PreferenceInsertInput.
// PreferenceInsertInput has userId.
preferencesSet: {
// * Default preferences
userId: insertUserOne.userId,
preferredComplexity: 'general',
preferredLength: 'detailed',
Expand All @@ -138,7 +141,7 @@ export async function POST(req: NextRequest) {
},
})

if (!insertPreferenceResults) {
if (error || !preference) {
// console.error('Failed to create your account ——> ', error)
throw new Error(
'Failed to create your account, an error occurred while creating your profile.',
Expand Down
5 changes: 1 addition & 4 deletions apps/pro-web/app/b/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,5 @@ import type { PageProps } from '@/types'

export default async function BotPage(props: PageProps) {
// When no bot is selected, pass null/undefined to show welcome view
return (
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
<BotProfileThreadSection threads={[]} count={0} chatbot={null} />
)
return <BotProfileThreadSection threads={[]} count={0} chatbot={null} />
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export function BrowseChatbotDesktopDetails({
className="text-base text-black dark:text-white min-h-24 onboarding-chatbot-card__content"
components={memoizedMarkdownComponents()}
>
{chatbot.description}
{chatbot.description || ''}
</MemoizedReactMarkdown>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function BrowseChatbotMobileDetails({
className="pt-2.5 text-base text-black dark:text-white min-h-24 onboarding-chatbot-card__content [&ul]:flex"
components={memoizedMarkdownComponents()}
>
{chatbot.description}
{chatbot.description || ''}
</MemoizedReactMarkdown>
</CardContent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function SelectedBotMobileView({
className="pt-6 text-base text-black dark:text-white min-h-24 onboarding-chatbot-card__content"
components={memoizedMarkdownComponents()}
>
{description}
{description || ''}
</MemoizedReactMarkdown>
</CardContent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function OnboardingChatbotDetails({
>
{isWelcomeView
? 'Here you can create new threads and share them to your network! Navigate with the sidebar and pick any bot of your interest.'
: description}
: description || ''}
</MemoizedReactMarkdown>

{isWelcomeView && (
Expand Down
5 changes: 3 additions & 2 deletions apps/pro-web/components/routes/pro/chat-message-pro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ export function ChatMessagePro({
<div className="flex-1 pr-1 space-y-2 overflow-hidden">
<MemoizedReactMarkdown
className="min-w-full prose break-words dark:prose-invert prose-p:leading-relaxed prose-pre:p-0"
remarkPlugins={[remarkGfm, rehypeMathJax, remarkRehype]}
remarkPlugins={[remarkGfm]}
Copy link
Member

Choose a reason for hiding this comment

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

We need to review for regressions—however, I have noticed issues with a few formulas and MathJax nor Rehype was picking them hence, I had to create a custom rule to support them, but that worked partially. We need to do a deep test with different formulas. This is important due there are plenty of startups that needs maths formulas to get things done. Maths are everywhere!

rehypePlugins={[rehypeMathJax]}
components={memoizedMarkdownComponents(
!(isBrowseView || isProfileView)
? {
Expand All @@ -117,7 +118,7 @@ export function ChatMessagePro({
: undefined,
)}
>
{cleanMessage.content}
{cleanMessage.content || ''}
</MemoizedReactMarkdown>

{actionRequired && (
Expand Down
Loading