Skip to content

Commit f7eef61

Browse files
waleedlatif1claude
andcommitted
fix(knowledge): use per-KB embedding model in v1 search route
The v1 search endpoint was passing undefined to generateSearchEmbedding, which silently fell back to text-embedding-3-small. KBs created while KB_EMBEDDING_MODEL=gemini-embedding-001 (or any non-default) would have their queries embedded with the wrong model. Now resolves the model from the KB rows like the internal route, with the same multi-model guard. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 687b7f5 commit f7eef61

1 file changed

Lines changed: 22 additions & 7 deletions

File tree

  • apps/sim/app/api/v1/knowledge/search

apps/sim/app/api/v1/knowledge/search/route.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,14 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
8484
const accessChecks = await Promise.all(
8585
knowledgeBaseIds.map((kbId) => checkKnowledgeBaseAccess(kbId, userId))
8686
)
87-
const accessibleKbIds = knowledgeBaseIds.filter(
88-
(_, idx) =>
89-
accessChecks[idx]?.hasAccess &&
90-
accessChecks[idx]?.knowledgeBase?.workspaceId === workspaceId
91-
)
87+
const accessibleKbs = knowledgeBaseIds
88+
.map((_, idx) => accessChecks[idx])
89+
.filter(
90+
(ac): ac is NonNullable<typeof ac> =>
91+
Boolean(ac?.hasAccess) && ac?.knowledgeBase?.workspaceId === workspaceId
92+
)
93+
.map((ac) => ac.knowledgeBase!)
94+
const accessibleKbIds = accessibleKbs.map((kb) => kb.id)
9295

9396
if (accessibleKbIds.length === 0) {
9497
return NextResponse.json(
@@ -173,6 +176,18 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
173176
const hasQuery = query && query.trim().length > 0
174177
const hasFilters = structuredFilters.length > 0
175178

179+
const embeddingModels = Array.from(new Set(accessibleKbs.map((kb) => kb.embeddingModel)))
180+
if (hasQuery && embeddingModels.length > 1) {
181+
return NextResponse.json(
182+
{
183+
error:
184+
'Selected knowledge bases use different embedding models and cannot be searched together. Search them separately.',
185+
},
186+
{ status: 400 }
187+
)
188+
}
189+
const queryEmbeddingModel = embeddingModels[0]
190+
176191
let results: SearchResult[]
177192

178193
if (!hasQuery && hasFilters) {
@@ -184,7 +199,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
184199
} else if (hasQuery && hasFilters) {
185200
const strategy = getQueryStrategy(accessibleKbIds.length, topK)
186201
const queryVector = JSON.stringify(
187-
await generateSearchEmbedding(query!, undefined, workspaceId)
202+
await generateSearchEmbedding(query!, queryEmbeddingModel, workspaceId)
188203
)
189204
results = await handleTagAndVectorSearch({
190205
knowledgeBaseIds: accessibleKbIds,
@@ -196,7 +211,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
196211
} else if (hasQuery) {
197212
const strategy = getQueryStrategy(accessibleKbIds.length, topK)
198213
const queryVector = JSON.stringify(
199-
await generateSearchEmbedding(query!, undefined, workspaceId)
214+
await generateSearchEmbedding(query!, queryEmbeddingModel, workspaceId)
200215
)
201216
results = await handleVectorOnlySearch({
202217
knowledgeBaseIds: accessibleKbIds,

0 commit comments

Comments
 (0)