fix inbox lifecycle downstream contracts

This commit is contained in:
_Kerman
2026-07-31 22:00:39 +08:00
parent 8e88b17c9f
commit afedf18ccf
219 changed files with 5660 additions and 4556 deletions

View File

@@ -0,0 +1,46 @@
import { describe, expect, it } from 'vitest'
import { normalizeLlmFailure } from '../src/adapter-failure.ts'
describe('adapter failure normalization', () => {
it('contains hostile non-Error coercion', () => {
const thrown = { [Symbol.toPrimitive]: () => { throw new Error('coercion failed') } }
expect(normalizeLlmFailure(thrown)).toEqual({ message: 'LLM adapter failed', code: 'UNKNOWN' })
})
it('contains hostile Error property reflection', () => {
const withFailure = new Error('provider failed') as Error & { failure: unknown; code: string }
withFailure.failure = { message: 'provider failed', code: 'FOREIGN' }
withFailure.code = 'FOREIGN'
const hostileCode = new Proxy(withFailure, {
getOwnPropertyDescriptor(target, property) {
if (property === 'code') throw new Error('code descriptor failed')
return Reflect.getOwnPropertyDescriptor(target, property)
},
})
expect(normalizeLlmFailure(hostileCode)).toEqual({ message: 'provider failed', code: 'UNKNOWN' })
const hostileFailure = new Proxy(new Error('provider failed'), {
getOwnPropertyDescriptor() { throw new Error('failure descriptor failed') },
})
expect(normalizeLlmFailure(hostileFailure)).toEqual({ message: 'provider failed', code: 'UNKNOWN' })
})
it('rejects malformed or accessor-backed failure snapshots', () => {
const malformed = new Error('provider failed') as Error & { failure: unknown; code: string }
malformed.failure = { message: 'provider failed', code: 'FOREIGN', requestId: '' }
malformed.code = 'FOREIGN'
expect(normalizeLlmFailure(malformed)).toEqual({ message: 'provider failed', code: 'UNKNOWN' })
const accessorBacked = new Error('provider failed') as Error & { failure: unknown }
accessorBacked.failure = Object.defineProperty({}, 'message', {
get() { throw new Error('failure getter failed') },
})
expect(normalizeLlmFailure(accessorBacked)).toEqual({ message: 'provider failed', code: 'UNKNOWN' })
})
it('falls back when an Error message accessor throws', () => {
const error = new Error('provider failed')
Object.defineProperty(error, 'message', { get() { throw new Error('message getter failed') } })
expect(normalizeLlmFailure(error)).toEqual({ message: 'LLM adapter failed', code: 'UNKNOWN' })
})
})

View File

@@ -489,6 +489,23 @@ describe('LlmService', () => {
expect(cleanupCalls).toBe(1)
})
it('allows downstream close when an adapter iterator has no return method', async () => {
const adapter = new class extends LlmAdapter {
stream(_options: GenerateOptions): AsyncIterable<StreamChunk> {
return {
[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {
return { next: () => Promise.resolve({ done: false, value: SCRIPT[0]! }) }
},
}
}
}()
const ctx = new Context()
await ctx.plugin(LlmService)
ctx.llm.registerAdapter(['test'], adapter)
for await (const _chunk of ctx.llm.stream({ provider: 'test', model: 'test', messages: [] })) break
})
it('unregisters adapters when the owning fiber is disposed (HMR safety)', async () => {
const ctx = new Context()
await ctx.plugin(LlmService)