aa2c7dfed3
Add semi-automatic knowledge suggestions and user-confirmed injection across chat, interactive, auto, and wizard modes; fix writing flows to persist full systemPrompt in contextJson. Co-authored-by: Cursor <cursoragent@cursor.com>
81 lines
3.0 KiB
TypeScript
81 lines
3.0 KiB
TypeScript
import { describe, it, expect, afterEach } from 'vitest'
|
|
import { DatabaseSync } from 'node:sqlite'
|
|
import { migrate } from '../../src/main/db/migrate'
|
|
import { VolumeRepository } from '../../src/main/db/repositories/volume.repo'
|
|
import { ChapterRepository } from '../../src/main/db/repositories/chapter.repo'
|
|
import { KnowledgeRepository } from '../../src/main/db/repositories/knowledge.repo'
|
|
import { KnowledgeRetrievalService } from '../../src/main/services/knowledge-retrieval.service'
|
|
import type { SqliteDb } from '../../src/main/db/types'
|
|
|
|
describe('KnowledgeRetrievalService', () => {
|
|
let db: SqliteDb
|
|
afterEach(() => db?.close())
|
|
|
|
it('UT-CTX-01: ranks by importance + chapter proximity + goal match', () => {
|
|
db = new DatabaseSync(':memory:')
|
|
migrate(db)
|
|
const volId = new VolumeRepository(db).create('卷一', 0).id
|
|
const chapterRepo = new ChapterRepository(db)
|
|
const cur = chapterRepo.create(volId, '当前章', 5, '<p>x</p>')
|
|
const near = chapterRepo.create(volId, '近章', 4, '<p>x</p>')
|
|
chapterRepo.create(volId, '远章', 0, '<p>x</p>')
|
|
const repo = new KnowledgeRepository(db)
|
|
const low = repo.create({
|
|
type: 'fact',
|
|
title: '无关事实',
|
|
content: '普通内容',
|
|
importance: 2,
|
|
status: 'approved'
|
|
})
|
|
const high = repo.create({
|
|
type: 'foreshadow',
|
|
title: '测灵石异常',
|
|
content: '测灵石在入门考核中发热',
|
|
importance: 5,
|
|
status: 'approved',
|
|
foreshadowStatus: 'buried',
|
|
sourceChapterId: near.id
|
|
})
|
|
const service = new KnowledgeRetrievalService(db)
|
|
const result = service.suggest({
|
|
currentChapterId: cur.id,
|
|
goalText: '测灵石入门考核',
|
|
topN: 5
|
|
})
|
|
expect(result[0].entry.id).toBe(high.id)
|
|
expect(result[0].score).toBeGreaterThan(
|
|
result.find((r) => r.entry.id === low.id)!.score
|
|
)
|
|
expect(result[0].reasons.length).toBeGreaterThan(0)
|
|
})
|
|
|
|
it('UT-CTX-04: resolved foreshadow scores lower than buried', () => {
|
|
db = new DatabaseSync(':memory:')
|
|
migrate(db)
|
|
const volId = new VolumeRepository(db).create('卷一', 0).id
|
|
const chId = new ChapterRepository(db).create(volId, '章', 0).id
|
|
const repo = new KnowledgeRepository(db)
|
|
const buried = repo.create({
|
|
type: 'foreshadow',
|
|
title: '埋设伏笔',
|
|
importance: 3,
|
|
status: 'approved',
|
|
foreshadowStatus: 'buried',
|
|
sourceChapterId: chId
|
|
})
|
|
const resolved = repo.create({
|
|
type: 'foreshadow',
|
|
title: '已回收伏笔',
|
|
importance: 3,
|
|
status: 'approved',
|
|
foreshadowStatus: 'resolved',
|
|
sourceChapterId: chId
|
|
})
|
|
const service = new KnowledgeRetrievalService(db)
|
|
const scores = service.suggest({ currentChapterId: chId, topN: 10 })
|
|
const buriedScore = scores.find((s) => s.entry.id === buried.id)!.score
|
|
const resolvedScore = scores.find((s) => s.entry.id === resolved.id)!.score
|
|
expect(buriedScore).toBeGreaterThan(resolvedScore)
|
|
})
|
|
})
|