feat: publish v1.0.0-rc.36-custom.1
This commit is contained in:
commit
3a7e8f3b54
2381 files changed
+551494
No files matched your search
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright (C) 2023-2026 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import type { ChatCompletionRequest } from '../types'
|
||||
import { createStreamRequestController } from './use-stream-request'
|
||||
|
||||
function deferred<T>() {
|
||||
let resolve!: (value: T) => void
|
||||
const promise = new Promise<T>((promiseResolve) => {
|
||||
resolve = promiseResolve
|
||||
})
|
||||
return { promise, resolve }
|
||||
}
|
||||
|
||||
class FakeStreamSource {
|
||||
readyState = 0
|
||||
closed = false
|
||||
streamed = false
|
||||
private listeners = new Map<
|
||||
string,
|
||||
Array<(event: Event & { data?: string; readyState?: number }) => void>
|
||||
>()
|
||||
|
||||
addEventListener(
|
||||
type: string,
|
||||
listener: (event: Event & { data?: string; readyState?: number }) => void
|
||||
) {
|
||||
const listeners = this.listeners.get(type) ?? []
|
||||
listeners.push(listener)
|
||||
this.listeners.set(type, listeners)
|
||||
}
|
||||
|
||||
close() {
|
||||
this.closed = true
|
||||
}
|
||||
|
||||
stream() {
|
||||
this.streamed = true
|
||||
}
|
||||
|
||||
emit(type: string, data?: string) {
|
||||
for (const listener of this.listeners.get(type) ?? []) {
|
||||
listener({ data, readyState: this.readyState } as Event & {
|
||||
data?: string
|
||||
readyState?: number
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const payload: ChatCompletionRequest = {
|
||||
model: 'test-model',
|
||||
messages: [{ role: 'user', content: 'hello' }],
|
||||
stream: true,
|
||||
}
|
||||
|
||||
const noopCallbacks = {
|
||||
onUpdate: () => undefined,
|
||||
onComplete: () => undefined,
|
||||
onError: () => undefined,
|
||||
}
|
||||
|
||||
describe('latest-wins stream request coordination', () => {
|
||||
test('only creates a stream for the latest header request', async () => {
|
||||
const firstHeaders = deferred<Record<string, string>>()
|
||||
const secondHeaders = deferred<Record<string, string>>()
|
||||
let headerRequest = 0
|
||||
const sources: FakeStreamSource[] = []
|
||||
const controller = createStreamRequestController({
|
||||
getHeaders: () => {
|
||||
headerRequest += 1
|
||||
return headerRequest === 1
|
||||
? firstHeaders.promise
|
||||
: secondHeaders.promise
|
||||
},
|
||||
createSource: () => {
|
||||
const source = new FakeStreamSource()
|
||||
sources.push(source)
|
||||
return source
|
||||
},
|
||||
setStreaming: () => undefined,
|
||||
})
|
||||
|
||||
const first = controller.send(payload, noopCallbacks)
|
||||
const second = controller.send(payload, noopCallbacks)
|
||||
firstHeaders.resolve({ Authorization: 'Bearer stale' })
|
||||
await first
|
||||
expect(sources.length).toBe(0)
|
||||
|
||||
secondHeaders.resolve({ Authorization: 'Bearer current' })
|
||||
await second
|
||||
expect(sources.length).toBe(1)
|
||||
expect(sources[0]?.streamed).toBe(true)
|
||||
})
|
||||
|
||||
test('stop cancels a request that is still waiting for headers', async () => {
|
||||
const headers = deferred<Record<string, string>>()
|
||||
let sourceCount = 0
|
||||
const controller = createStreamRequestController({
|
||||
getHeaders: () => headers.promise,
|
||||
createSource: () => {
|
||||
sourceCount += 1
|
||||
return new FakeStreamSource()
|
||||
},
|
||||
setStreaming: () => undefined,
|
||||
})
|
||||
|
||||
const request = controller.send(payload, noopCallbacks)
|
||||
controller.stop()
|
||||
headers.resolve({ Authorization: 'Bearer ignored' })
|
||||
await request
|
||||
|
||||
expect(sourceCount).toBe(0)
|
||||
})
|
||||
|
||||
test('dispose cancels a pending header request without a state update', async () => {
|
||||
const headers = deferred<Record<string, string>>()
|
||||
const streamingStates: boolean[] = []
|
||||
let sourceCount = 0
|
||||
const controller = createStreamRequestController({
|
||||
getHeaders: () => headers.promise,
|
||||
createSource: () => {
|
||||
sourceCount += 1
|
||||
return new FakeStreamSource()
|
||||
},
|
||||
setStreaming: (streaming) => streamingStates.push(streaming),
|
||||
})
|
||||
|
||||
const request = controller.send(payload, noopCallbacks)
|
||||
controller.dispose()
|
||||
headers.resolve({ Authorization: 'Bearer ignored' })
|
||||
await request
|
||||
|
||||
expect(sourceCount).toBe(0)
|
||||
expect(streamingStates).toEqual([false])
|
||||
})
|
||||
|
||||
test('closes the previous source and ignores all of its later events', async () => {
|
||||
const nextHeaders = deferred<Record<string, string>>()
|
||||
let headerRequest = 0
|
||||
const sources: FakeStreamSource[] = []
|
||||
const updates: string[] = []
|
||||
const controller = createStreamRequestController({
|
||||
getHeaders: () => {
|
||||
headerRequest += 1
|
||||
if (headerRequest === 1) {
|
||||
return Promise.resolve({ Authorization: 'Bearer first' })
|
||||
}
|
||||
return nextHeaders.promise
|
||||
},
|
||||
createSource: () => {
|
||||
const source = new FakeStreamSource()
|
||||
sources.push(source)
|
||||
return source
|
||||
},
|
||||
setStreaming: () => undefined,
|
||||
})
|
||||
const callbacks = {
|
||||
onUpdate: (_type: 'reasoning' | 'content', chunk: string) =>
|
||||
updates.push(chunk),
|
||||
onComplete: () => undefined,
|
||||
onError: () => undefined,
|
||||
}
|
||||
|
||||
await controller.send(payload, callbacks)
|
||||
const second = controller.send(payload, callbacks)
|
||||
expect(sources[0]?.closed).toBe(true)
|
||||
sources[0]?.emit(
|
||||
'message',
|
||||
JSON.stringify({ choices: [{ delta: { content: 'stale' } }] })
|
||||
)
|
||||
|
||||
nextHeaders.resolve({ Authorization: 'Bearer second' })
|
||||
await second
|
||||
sources[1]?.emit(
|
||||
'message',
|
||||
JSON.stringify({ choices: [{ delta: { content: 'current' } }] })
|
||||
)
|
||||
|
||||
expect(updates).toEqual(['current'])
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user