feat: enhance local knowledge retrieval

This commit is contained in:
lofyer
2026-08-12 21:45:47 +08:00
parent e0e5a8c1b3
commit 111f487e20
65 changed files with 13517 additions and 1155 deletions
+144
View File
@@ -0,0 +1,144 @@
import { describe, expect, it } from 'vitest'
import {
defaultKnowledgeOntologySettings,
getKnowledgeOntologyDisplayDefinitions,
isRelationEndpointAllowed,
knowledgeOntologySettingsSchema,
normalizeEntityTypeAlias,
normalizeRelationTypeAlias
} from './knowledge-ontology'
describe('knowledge ontology contract', () => {
it('provides the version 1 controlled defaults and useful aliases', () => {
expect(defaultKnowledgeOntologySettings.version).toBe(1)
expect(
defaultKnowledgeOntologySettings.entityTypes.map(({ id }) => id)
).toEqual([
'PERSON',
'ORGANIZATION',
'EVENT',
'LOCATION',
'DOCUMENT',
'CONCEPT'
])
expect(normalizeEntityTypeAlias('people')).toBe('PERSON')
expect(normalizeEntityTypeAlias('人员')).toBe('PERSON')
expect(normalizeEntityTypeAlias('公司')).toBe('ORGANIZATION')
expect(normalizeEntityTypeAlias('uncontrolled legacy type')).toBe('CONCEPT')
expect(normalizeRelationTypeAlias('depends on')).toBe('DEPENDS_ON')
expect(normalizeRelationTypeAlias('依赖于')).toBe('DEPENDS_ON')
})
it('rejects noncanonical ids, collisions, missing fallback, and bad endpoints', () => {
const concept = {
id: 'CONCEPT',
name: { zh: '概念', en: 'Concept' },
aliases: ['topic']
}
expect(() =>
knowledgeOntologySettingsSchema.parse({
entityTypes: [concept, { ...concept, id: 'person' }],
relationTypes: []
})
).toThrow()
expect(() =>
knowledgeOntologySettingsSchema.parse({
entityTypes: [
concept,
{
id: 'PERSON',
name: { zh: '人物', en: 'Person' },
aliases: ['shared']
},
{
id: 'ORGANIZATION',
name: { zh: '组织', en: 'Organization' },
aliases: ['shared']
}
],
relationTypes: []
})
).toThrow()
expect(() =>
knowledgeOntologySettingsSchema.parse({
entityTypes: [
{
id: 'PERSON',
name: { zh: '人物', en: 'Person' },
aliases: []
}
],
relationTypes: []
})
).toThrow()
expect(() =>
knowledgeOntologySettingsSchema.parse({
entityTypes: [concept],
relationTypes: [
{
id: 'KNOWS',
name: { zh: '认识', en: 'Knows' },
aliases: [],
sourceTypes: ['MISSING']
}
]
})
).toThrow()
})
it('enforces optional relation endpoint constraints', () => {
const settings = knowledgeOntologySettingsSchema.parse({
entityTypes: [
{
id: 'CONCEPT',
name: { zh: '概念', en: 'Concept' },
aliases: []
},
{
id: 'PERSON',
name: { zh: '人物', en: 'Person' },
aliases: ['people']
},
{
id: 'ORGANIZATION',
name: { zh: '组织', en: 'Organization' },
aliases: ['company']
}
],
relationTypes: [
{
id: 'WORKS_FOR',
name: { zh: '任职于', en: 'Works for' },
aliases: ['works for'],
sourceTypes: ['PERSON'],
targetTypes: ['ORGANIZATION']
}
]
})
expect(isRelationEndpointAllowed('works for', 'people', 'company', settings)).toBe(
true
)
expect(
isRelationEndpointAllowed('WORKS_FOR', 'ORGANIZATION', 'PERSON', settings)
).toBe(false)
expect(isRelationEndpointAllowed('UNKNOWN', 'PERSON', 'ORGANIZATION', settings)).toBe(
false
)
})
it('returns localized, detached display data', () => {
const display = getKnowledgeOntologyDisplayDefinitions(
defaultKnowledgeOntologySettings,
'en'
)
expect(display.fallbackEntityType).toBe('CONCEPT')
expect(display.entityTypes.find(({ id }) => id === 'PERSON')?.label).toBe(
'Person'
)
display.entityTypes[0]?.aliases.push('local mutation')
expect(defaultKnowledgeOntologySettings.entityTypes[0]?.aliases).not.toContain(
'local mutation'
)
})
})