WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s

This commit is contained in:
yawan
2026-09-22 16:19:06 +08:00
commit f7fc992f57
3929 changed files with 1006607 additions and 0 deletions
@@ -0,0 +1,188 @@
package sqlite
import (
"context"
"fmt"
"strings"
"sync"
"testing"
"github.com/Tencent/WeKnora/internal/types"
sqlite_vec "github.com/asg017/sqlite-vec-go-bindings/cgo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
)
var registerSQLiteVec sync.Once
func newSQLiteRetrieverTestRepository(t *testing.T) *sqliteRepository {
t.Helper()
registerSQLiteVec.Do(sqlite_vec.Auto)
dbName := strings.NewReplacer("/", "_", " ", "_").Replace(t.Name())
db, err := gorm.Open(gormsqlite.Open(fmt.Sprintf("file:%s?mode=memory&cache=shared", dbName)), &gorm.Config{})
require.NoError(t, err)
sqlDB, err := db.DB()
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, sqlDB.Close())
})
repository, ok := NewSQLiteRetrieveEngineRepository(db).(*sqliteRepository)
require.True(t, ok)
return repository
}
func saveSQLiteTestVector(t *testing.T, repository *sqliteRepository, info *types.IndexInfo, embedding []float32) {
t.Helper()
require.NoError(t, repository.Save(context.Background(), info, map[string]any{
"embedding": map[string][]float32{info.SourceID: embedding},
}))
}
func sqliteTestIndex(chunkID, knowledgeBaseID, knowledgeID, tagID string, enabled bool) *types.IndexInfo {
return &types.IndexInfo{
Content: chunkID,
SourceID: "source-" + chunkID,
SourceType: types.ChunkSourceType,
ChunkID: chunkID,
KnowledgeID: knowledgeID,
KnowledgeBaseID: knowledgeBaseID,
TagID: tagID,
IsEnabled: enabled,
}
}
func TestVectorRetrieveFiltersBeforeTopK(t *testing.T) {
testCases := []struct {
name string
blocker *types.IndexInfo
configure func(*types.RetrieveParams)
}{
{
name: "knowledge base",
blocker: sqliteTestIndex("blocker", "kb-other", "knowledge-target", "tag-target", true),
configure: func(params *types.RetrieveParams) {
params.KnowledgeBaseIDs = []string{"kb-target"}
},
},
{
name: "knowledge",
blocker: sqliteTestIndex("blocker", "kb-target", "knowledge-other", "tag-target", true),
configure: func(params *types.RetrieveParams) {
params.KnowledgeIDs = []string{"knowledge-target"}
},
},
{
name: "tag",
blocker: sqliteTestIndex("blocker", "kb-target", "knowledge-target", "tag-other", true),
configure: func(params *types.RetrieveParams) {
params.TagIDs = []string{"tag-target"}
},
},
{
name: "enabled status",
blocker: sqliteTestIndex("blocker", "kb-target", "knowledge-target", "tag-target", false),
configure: func(_ *types.RetrieveParams) {},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
repository := newSQLiteRetrieverTestRepository(t)
saveSQLiteTestVector(t, repository, testCase.blocker, []float32{1, 0})
saveSQLiteTestVector(t, repository,
sqliteTestIndex("target", "kb-target", "knowledge-target", "tag-target", true),
[]float32{0.8, 0.6},
)
params := types.RetrieveParams{
Embedding: []float32{1, 0},
TopK: 1,
RetrieverType: types.VectorRetrieverType,
}
testCase.configure(&params)
results, err := repository.vectorRetrieve(context.Background(), params)
require.NoError(t, err)
require.Len(t, results, 1)
require.Len(t, results[0].Results, 1)
assert.Equal(t, "target", results[0].Results[0].ChunkID)
})
}
}
func TestVectorRetrieveZeroThresholdDoesNotFilter(t *testing.T) {
repository := newSQLiteRetrieverTestRepository(t)
saveSQLiteTestVector(t, repository,
sqliteTestIndex("anti-correlated", "kb-target", "knowledge-target", "tag-target", true),
[]float32{-1, 0},
)
results, err := repository.vectorRetrieve(context.Background(), types.RetrieveParams{
Embedding: []float32{1, 0},
KnowledgeBaseIDs: []string{"kb-target"},
TopK: 1,
Threshold: 0,
RetrieverType: types.VectorRetrieverType,
})
require.NoError(t, err)
require.Len(t, results, 1)
require.Len(t, results[0].Results, 1)
assert.Equal(t, "anti-correlated", results[0].Results[0].ChunkID)
assert.Less(t, results[0].Results[0].Score, 0.0)
}
func TestVectorRetrieveAppliesSimilarityThreshold(t *testing.T) {
repository := newSQLiteRetrieverTestRepository(t)
saveSQLiteTestVector(t, repository,
sqliteTestIndex("below-threshold", "kb-target", "knowledge-target", "tag-target", true),
[]float32{0.5, 0.8660254},
)
results, err := repository.vectorRetrieve(context.Background(), types.RetrieveParams{
Embedding: []float32{1, 0},
KnowledgeBaseIDs: []string{"kb-target"},
TopK: 1,
Threshold: 0.75,
RetrieverType: types.VectorRetrieverType,
})
require.NoError(t, err)
require.Len(t, results, 1)
assert.Empty(t, results[0].Results)
}
func TestRetrieveReturnsVectorQueryError(t *testing.T) {
repository := newSQLiteRetrieverTestRepository(t)
saveSQLiteTestVector(t, repository,
sqliteTestIndex("chunk", "kb-target", "knowledge-target", "tag-target", true),
[]float32{1, 0},
)
require.NoError(t, repository.db.Exec("DROP TABLE "+vecTableName(2)).Error)
results, err := repository.Retrieve(context.Background(), types.RetrieveParams{
Embedding: []float32{1, 0},
TopK: 1,
RetrieverType: types.VectorRetrieverType,
})
require.Error(t, err)
assert.Nil(t, results)
assert.Contains(t, err.Error(), "sqlite-vec query failed")
}
func TestRetrieveReturnsKeywordQueryError(t *testing.T) {
repository := newSQLiteRetrieverTestRepository(t)
require.NoError(t, repository.db.Exec("DROP TABLE IF EXISTS lite_embeddings_fts").Error)
results, err := repository.Retrieve(context.Background(), types.RetrieveParams{
Query: "missing fts table",
TopK: 1,
RetrieverType: types.KeywordsRetrieverType,
})
require.Error(t, err)
assert.Nil(t, results)
assert.Contains(t, err.Error(), "FTS5 query failed")
}