Skip to content

Commit 81f6557

Browse files
committed
cleanup, optimize and fix any lint issues in query, assistant routes
1 parent 81573bd commit 81f6557

File tree

7 files changed

+429
-247
lines changed

7 files changed

+429
-247
lines changed

apps/api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"@trpc/server": "^11.4.3",
2121
"autumn-js": "0.0.101-beta.1",
2222
"dayjs": "^1.11.13",
23-
"elysia": "^1.3.5",
23+
"elysia": "^1.3.6",
2424
"nats": "^2.29.3",
2525
"openai": "^5.9.0"
2626
}

apps/api/src/routes/assistant.ts

Lines changed: 74 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,53 @@
11
import { auth } from '@databuddy/auth';
22
import { db, websites } from '@databuddy/db';
3+
import { cacheable } from '@databuddy/redis';
34
import { eq } from 'drizzle-orm';
4-
import { Elysia, t } from 'elysia';
5+
import { Elysia } from 'elysia';
6+
import type { StreamingUpdate } from '../agent';
57
import {
68
type AssistantContext,
79
type AssistantRequest,
810
createStreamingResponse,
911
processAssistantRequest,
1012
} from '../agent';
1113
import { createRateLimitMiddleware } from '../middleware/rate-limit';
14+
import { AssistantRequestSchema } from '../schemas';
1215

13-
// ============================================================================
14-
// SCHEMAS
15-
// ============================================================================
16+
// biome-ignore lint/suspicious/useAwait: async generator function doesn't need await
17+
async function* createErrorResponse(
18+
message: string
19+
): AsyncGenerator<StreamingUpdate> {
20+
yield { type: 'error', content: message };
21+
}
1622

17-
const AssistantRequestSchema = t.Object({
18-
message: t.String(),
19-
website_id: t.String(),
20-
model: t.Optional(
21-
t.Union([t.Literal('chat'), t.Literal('agent'), t.Literal('agent-max')])
22-
),
23-
context: t.Optional(
24-
t.Object({
25-
previousMessages: t.Optional(
26-
t.Array(
27-
t.Object({
28-
role: t.Optional(t.String()),
29-
content: t.String(),
30-
})
31-
)
32-
),
33-
})
34-
),
35-
});
23+
const getCachedWebsite = cacheable(
24+
async (websiteId: string) => {
25+
try {
26+
const website = await db.query.websites.findFirst({
27+
where: eq(websites.id, websiteId),
28+
});
29+
return website || null;
30+
} catch {
31+
return null;
32+
}
33+
},
34+
{
35+
expireInSec: 300,
36+
prefix: 'assistant-website',
37+
staleWhileRevalidate: true,
38+
staleTime: 60,
39+
}
40+
);
41+
42+
async function validateWebsite(websiteId: string) {
43+
const website = await getCachedWebsite(websiteId);
3644

37-
// ============================================================================
38-
// ROUTER SETUP
39-
// ============================================================================
45+
if (!website) {
46+
return { success: false, error: 'Website not found' };
47+
}
48+
49+
return { success: true, website };
50+
}
4051

4152
export const assistant = new Elysia({ prefix: '/v1/assistant' })
4253
.use(createRateLimitMiddleware({ type: 'expensive' }))
@@ -56,39 +67,47 @@ export const assistant = new Elysia({ prefix: '/v1/assistant' })
5667
async ({ body, user }) => {
5768
const { message, website_id, model, context } = body;
5869

59-
// Get website info from the website_id in the body
60-
const website = await db.query.websites.findFirst({
61-
where: eq(websites.id, website_id),
62-
});
70+
try {
71+
const websiteValidation = await validateWebsite(website_id);
6372

64-
if (!website) {
65-
return createStreamingResponse(
66-
(async function* () {
67-
yield { type: 'error', content: 'Website not found' };
68-
})()
69-
);
70-
}
73+
if (!websiteValidation.success) {
74+
return createStreamingResponse(
75+
createErrorResponse(websiteValidation.error || 'Website not found')
76+
);
77+
}
78+
79+
const { website } = websiteValidation;
7180

72-
const assistantRequest: AssistantRequest = {
73-
message,
74-
website_id,
75-
website_hostname: website.domain,
76-
model: model || 'chat',
77-
context,
78-
};
81+
if (!website) {
82+
return createStreamingResponse(
83+
createErrorResponse('Website not found')
84+
);
85+
}
7986

80-
const assistantContext: AssistantContext = {
81-
user,
82-
website,
83-
debugInfo: {},
84-
};
87+
const assistantRequest: AssistantRequest = {
88+
message,
89+
website_id,
90+
website_hostname: website.domain,
91+
model: model || 'chat',
92+
context,
93+
};
8594

86-
// Process the assistant request and create streaming response
87-
const updates = processAssistantRequest(
88-
assistantRequest,
89-
assistantContext
90-
);
91-
return createStreamingResponse(updates);
95+
const assistantContext: AssistantContext = {
96+
user,
97+
website,
98+
debugInfo: {},
99+
};
100+
101+
const updates = processAssistantRequest(
102+
assistantRequest,
103+
assistantContext
104+
);
105+
return createStreamingResponse(updates);
106+
} catch (error) {
107+
const errorMessage =
108+
error instanceof Error ? error.message : 'Unknown error occurred';
109+
return createStreamingResponse(createErrorResponse(errorMessage));
110+
}
92111
},
93112
{
94113
body: AssistantRequestSchema,

0 commit comments

Comments
 (0)