fix(supervisor): expand bounded source aliases

This commit is contained in:
mesalogo
2026-10-07 17:15:00 +08:00
parent 425accf49d
commit e0607a153f
2 changed files with 10 additions and 7 deletions
@@ -52,13 +52,16 @@ const output = {
} }
describe('SupervisorService', () => { describe('SupervisorService', () => {
it('rejects a source alias when it identifies more than one input fragment', async () => { it('expands a source alias to all matching bounded input fragments', async () => {
const fragments = [0, 1].map(index => ({ ...evidence[0]!, id: `fragment-${index}`, const fragments = [0, 1].map(index => ({ ...evidence[0]!, id: `fragment-${index}`,
locator: { source: 'message:shared', start: index, end: index + 1 } })) locator: { source: 'message:shared', start: index, end: index + 1 } }))
const save = vi.fn()
const service = new SupervisorService({ collect: async () => fragments }, { summarize: async () => ({ const service = new SupervisorService({ collect: async () => fragments }, { summarize: async () => ({
...output, entities: [], events: [{ ...output.events[0], entityIds: [], sourceReferenceIds: ['message:shared'] }] ...output, entities: [], events: [{ ...output.events[0], entityIds: [], sourceReferenceIds: ['message:shared'] }]
}) }, { save: vi.fn() }) }) }, { save })
await expect(service.run(request)).rejects.toThrow('本次范围之外') const result = await service.run(request)
expect(result.output.events[0]!.sourceReferenceIds).toEqual(['fragment-0', 'fragment-1'])
expect(save).toHaveBeenCalledWith(result)
}) })
it('rejects invented persisted identities even when a local model id matches', async () => { it('rejects invented persisted identities even when a local model id matches', async () => {
const id = '00000000-0000-4000-8000-000000000001' const id = '00000000-0000-4000-8000-000000000001'
+4 -4
View File
@@ -137,11 +137,11 @@ function validateReferences(
for (const item of [...output.events, ...output.entities, ...output.entityChanges, ...output.relations]) { for (const item of [...output.events, ...output.entities, ...output.entityChanges, ...output.relations]) {
item.sourceReferenceIds = [...new Set(item.sourceReferenceIds.map(id => { item.sourceReferenceIds = [...new Set(item.sourceReferenceIds.map(id => {
if (evidenceIds.has(id)) return id if (evidenceIds.has(id)) return id
// Providers also copy the supplied locator.source. Resolve it only when this // Providers may copy the supplied locator.source. Expand it to the matching
// node contains exactly one fragment of that source, never to an entire message. // bounded fragments so a multi-fragment source never becomes an unbounded citation.
const matches = evidence.filter(source => source.locator?.source === id) const matches = evidence.filter(source => source.locator?.source === id)
return matches.length === 1 ? matches[0]!.id : id return matches.length ? matches.map(source => source.id) : [id]
}))] }).flat())]
} }
const references = [ const references = [
...output.events.flatMap((item) => item.sourceReferenceIds), ...output.events.flatMap((item) => item.sourceReferenceIds),