fix(edge): meter and size-cap knowledge embeddings in embed-chunks and search-knowledge
This commit is contained in:
parent
b35676c75c
commit
1afaea7214
12 changed files with 1111 additions and 270 deletions
|
|
@ -0,0 +1,70 @@
|
|||
// server/supabase/functions/embed-chunks/supabase-knowledge-store.ts
|
||||
// KnowledgeIndexStore adapter over the service-role Supabase client.
|
||||
|
||||
import type { createClient } from '@supabase/supabase-js'
|
||||
import { type KnowledgeChunkRow, type KnowledgeIndexStore, KnowledgeStorageError } from './handler.ts'
|
||||
|
||||
type SupabaseClient = ReturnType<typeof createClient>
|
||||
|
||||
export function createSupabaseKnowledgeStore(client: SupabaseClient): KnowledgeIndexStore {
|
||||
return {
|
||||
async documentOwner(documentId) {
|
||||
const { data, error } = await client
|
||||
.from('knowledge_documents')
|
||||
.select('id,user_id')
|
||||
.eq('id', documentId)
|
||||
.maybeSingle()
|
||||
if (error) throw new KnowledgeStorageError()
|
||||
const row = data as { user_id?: unknown } | null
|
||||
return row && typeof row.user_id === 'string' ? row.user_id : null
|
||||
},
|
||||
async countChunks(documentId, pendingOnly) {
|
||||
let query = client
|
||||
.from('knowledge_chunks')
|
||||
.select('id', { count: 'exact', head: true })
|
||||
.eq('document_id', documentId)
|
||||
if (pendingOnly) query = query.is('embedding', null)
|
||||
const { count, error } = await query
|
||||
if (error) throw new KnowledgeStorageError()
|
||||
return count
|
||||
},
|
||||
async listPendingChunks(documentId, limit) {
|
||||
const { data, error } = await client
|
||||
.from('knowledge_chunks')
|
||||
.select('id,content')
|
||||
.eq('document_id', documentId)
|
||||
.is('embedding', null)
|
||||
.order('chunk_index', { ascending: true })
|
||||
.limit(limit)
|
||||
if (error) throw new KnowledgeStorageError()
|
||||
return (data ?? []) as KnowledgeChunkRow[]
|
||||
},
|
||||
async saveEmbedding(documentId, chunkId, embedding) {
|
||||
const { error } = await client
|
||||
.from('knowledge_chunks')
|
||||
.update({ embedding })
|
||||
.eq('id', chunkId)
|
||||
.eq('document_id', documentId)
|
||||
return !error
|
||||
},
|
||||
async clearIndexed(documentId, userId) {
|
||||
let query = client
|
||||
.from('knowledge_documents')
|
||||
.update({ indexed: false, indexed_at: null })
|
||||
.eq('id', documentId)
|
||||
if (userId !== null) query = query.eq('user_id', userId)
|
||||
const { error } = await query
|
||||
return !error
|
||||
},
|
||||
async markIndexed(documentId, userId) {
|
||||
const { data, error } = await client
|
||||
.from('knowledge_documents')
|
||||
.update({ indexed: true, indexed_at: new Date().toISOString() })
|
||||
.eq('id', documentId)
|
||||
.eq('user_id', userId)
|
||||
.select('id')
|
||||
.maybeSingle()
|
||||
return !error && Boolean(data)
|
||||
},
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue