Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03k
1import {createParser, type EventSourceMessage, type EventSourceParser} from 'eventsource-parser'2 3import {ErrorEvent, flattenError, syntaxError} from './errors.js'4import type {5 AddEventListenerOptions,6 EventListenerOptions,7 EventListenerOrEventListenerObject,8 EventSourceEventMap,9 EventSourceFetchInit,10 EventSourceInit,11 FetchLike,12 FetchLikeResponse,13} from './types.js'14 15/**16 * An `EventSource` instance opens a persistent connection to an HTTP server, which sends events17 * in `text/event-stream` format. The connection remains open until closed by calling `.close()`.18 *19 * @public20 * @example21 * ```js22 * const eventSource = new EventSource('https://example.com/stream')23 * eventSource.addEventListener('error', (error) => {24 * console.error(error)25 * })26 * eventSource.addEventListener('message', (event) => {27 * console.log('Received message:', event.data)28 * })29 * ```30 */31export class EventSource extends EventTarget {32 /**33 * ReadyState representing an EventSource currently trying to connect34 *35 * @public36 */37 static CONNECTING = 0 as const38 39 /**40 * ReadyState representing an EventSource connection that is open (eg connected)41 *42 * @public43 */44 static OPEN = 1 as const45 46 /**47 * ReadyState representing an EventSource connection that is closed (eg disconnected)48 *49 * @public50 */51 static CLOSED = 2 as const52 53 /**54 * ReadyState representing an EventSource currently trying to connect55 *56 * @public57 */58 readonly CONNECTING = 0 as const59 60 /**61 * ReadyState representing an EventSource connection that is open (eg connected)62 *63 * @public64 */65 readonly OPEN = 1 as const66 67 /**68 * ReadyState representing an EventSource connection that is closed (eg disconnected)69 *70 * @public71 */72 readonly CLOSED = 2 as const73 74 /**75 * Returns the state of this EventSource object's connection. It can have the values described below.76 *77 * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)78 *79 * Note: typed as `number` instead of `0 | 1 | 2` for compatibility with the `EventSource` interface,80 * defined in the TypeScript `dom` library.81 *82 * @public83 */84 public get readyState(): number {85 return this.#readyState86 }87 88 /**89 * Returns the URL providing the event stream.90 *91 * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)92 *93 * @public94 */95 public get url(): string {96 return this.#url.href97 }98 99 /**100 * Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise.101 *102 * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)103 */104 public get withCredentials(): boolean {105 return this.#withCredentials106 }107 108 /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */109 public get onerror(): ((ev: ErrorEvent) => unknown) | null {110 return this.#onError111 }112 public set onerror(value: ((ev: ErrorEvent) => unknown) | null) {113 this.#onError = value114 }115 116 /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */117 public get onmessage(): ((ev: MessageEvent) => unknown) | null {118 return this.#onMessage119 }120 public set onmessage(value: ((ev: MessageEvent) => unknown) | null) {121 this.#onMessage = value122 }123 124 /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */125 public get onopen(): ((ev: Event) => unknown) | null {126 return this.#onOpen127 }128 public set onopen(value: ((ev: Event) => unknown) | null) {129 this.#onOpen = value130 }131 132 override addEventListener<K extends keyof EventSourceEventMap>(133 type: K,134 listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,135 options?: boolean | AddEventListenerOptions,136 ): void137 override addEventListener(138 type: string,139 listener: (this: EventSource, event: MessageEvent) => unknown,140 options?: boolean | AddEventListenerOptions,141 ): void142 override addEventListener(143 type: string,144 listener: EventListenerOrEventListenerObject,145 options?: boolean | AddEventListenerOptions,146 ): void147 override addEventListener(148 type: string,149 listener:150 | ((this: EventSource, event: MessageEvent) => unknown)151 | EventListenerOrEventListenerObject,152 options?: boolean | AddEventListenerOptions,153 ): void {154 const listen = listener as (this: EventSource, event: Event) => unknown155 super.addEventListener(type, listen, options)156 }157 158 override removeEventListener<K extends keyof EventSourceEventMap>(159 type: K,160 listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,161 options?: boolean | EventListenerOptions,162 ): void163 override removeEventListener(164 type: string,165 listener: (this: EventSource, event: MessageEvent) => unknown,166 options?: boolean | EventListenerOptions,167 ): void168 override removeEventListener(169 type: string,170 listener: EventListenerOrEventListenerObject,171 options?: boolean | EventListenerOptions,172 ): void173 override removeEventListener(174 type: string,175 listener:176 | ((this: EventSource, event: MessageEvent) => unknown)177 | EventListenerOrEventListenerObject,178 options?: boolean | EventListenerOptions,179 ): void {180 const listen = listener as (this: EventSource, event: Event) => unknown181 super.removeEventListener(type, listen, options)182 }183 184 constructor(url: string | URL, eventSourceInitDict?: EventSourceInit) {185 super()186 187 try {188 if (url instanceof URL) {189 this.#url = url190 } else if (typeof url === 'string') {191 this.#url = new URL(url, getBaseURL())192 } else {193 throw new Error('Invalid URL')194 }195 } catch (err) {196 throw syntaxError('An invalid or illegal string was specified')197 }198 199 this.#parser = createParser({200 onEvent: this.#onEvent,201 onRetry: this.#onRetryChange,202 })203 204 this.#readyState = this.CONNECTING205 this.#reconnectInterval = 3000206 this.#fetch = eventSourceInitDict?.fetch ?? globalThis.fetch207 this.#withCredentials = eventSourceInitDict?.withCredentials ?? false208 209 this.#connect()210 }211 212 /**213 * Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.214 *215 * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)216 *217 * @public218 */219 close(): void {220 if (this.#reconnectTimer) clearTimeout(this.#reconnectTimer)221 if (this.#readyState === this.CLOSED) return222 if (this.#controller) this.#controller.abort()223 this.#readyState = this.CLOSED224 this.#controller = undefined225 }226 227 // PRIVATES FOLLOW228 229 /**230 * Current connection state231 *232 * @internal233 */234 #readyState: number235 236 /**237 * Original URL used to connect.238 *239 * Note that this will stay the same even after a redirect.240 *241 * @internal242 */243 #url: URL244 245 /**246 * The destination URL after a redirect. Is reset on reconnection.247 *248 * @internal249 */250 #redirectUrl: URL | undefined251 252 /**253 * Whether to include credentials in the request254 *255 * @internal256 */257 #withCredentials: boolean258 259 /**260 * The fetch implementation to use261 *262 * @internal263 */264 #fetch: FetchLike265 266 /**267 * The reconnection time in milliseconds268 *269 * @internal270 */271 #reconnectInterval: number272 273 /**274 * Reference to an ongoing reconnect attempt, if any275 *276 * @internal277 */278 #reconnectTimer: ReturnType<typeof setTimeout> | undefined279 280 /**281 * The last event ID seen by the EventSource, which will be sent as `Last-Event-ID` in the282 * request headers on a reconnection attempt.283 *284 * @internal285 */286 #lastEventId: string | null = null287 288 /**289 * The AbortController instance used to abort the fetch request290 *291 * @internal292 */293 #controller: AbortController | undefined294 295 /**296 * Instance of an EventSource parser (`eventsource-parser` npm module)297 *298 * @internal299 */300 #parser: EventSourceParser301 302 /**303 * Holds the current error handler, attached through `onerror` property directly.304 * Note that `addEventListener('error', …)` will not be stored here.305 *306 * @internal307 */308 #onError: ((ev: ErrorEvent) => unknown) | null = null309 310 /**311 * Holds the current message handler, attached through `onmessage` property directly.312 * Note that `addEventListener('message', …)` will not be stored here.313 *314 * @internal315 */316 #onMessage: ((ev: MessageEvent) => unknown) | null = null317 318 /**319 * Holds the current open handler, attached through `onopen` property directly.320 * Note that `addEventListener('open', …)` will not be stored here.321 *322 * @internal323 */324 #onOpen: ((ev: Event) => unknown) | null = null325 326 /**327 * Connect to the given URL and start receiving events328 *329 * @internal330 */331 #connect() {332 this.#readyState = this.CONNECTING333 this.#controller = new AbortController()334 335 // Browser tests are failing if we directly call `this.#fetch()`, thus the indirection.336 const fetch = this.#fetch337 fetch(this.#url, this.#getRequestOptions())338 .then(this.#onFetchResponse)339 .catch(this.#onFetchError)340 }341 342 /**343 * Handles the fetch response344 *345 * @param response - The Fetch(ish) response346 * @internal347 */348 #onFetchResponse = async (response: FetchLikeResponse) => {349 this.#parser.reset()350 351 const {body, redirected, status, headers} = response352 353 // [spec] a client can be told to stop reconnecting using the HTTP 204 No Content response code.354 if (status === 204) {355 // We still need to emit an error event - this mirrors the browser behavior,356 // and without it there is no way to tell the user that the connection was closed.357 this.#failConnection('Server sent HTTP 204, not reconnecting', 204)358 this.close()359 return360 }361 362 // [spec] …Event stream requests can be redirected using HTTP 301 and 307 redirects as with363 // [spec] normal HTTP requests.364 // Spec does not say anything about other redirect codes (302, 308), but this seems an365 // unintended omission, rather than a feature. Browsers will happily redirect on other 3xxs's.366 if (redirected) {367 this.#redirectUrl = new URL(response.url)368 } else {369 this.#redirectUrl = undefined370 }371 372 // [spec] if res's status is not 200, …, then fail the connection.373 if (status !== 200) {374 this.#failConnection(`Non-200 status code (${status})`, status)375 return376 }377 378 // [spec] …or if res's `Content-Type` is not `text/event-stream`, then fail the connection.379 const contentType = headers.get('content-type') || ''380 if (!contentType.startsWith('text/event-stream')) {381 this.#failConnection('Invalid content type, expected "text/event-stream"', status)382 return383 }384 385 // [spec] …if the readyState attribute is set to a value other than CLOSED…386 if (this.#readyState === this.CLOSED) {387 return388 }389 390 // [spec] …sets the readyState attribute to OPEN and fires an event391 // [spec] …named open at the EventSource object.392 this.#readyState = this.OPEN393 394 const openEvent = new Event('open')395 this.#onOpen?.(openEvent)396 this.dispatchEvent(openEvent)397 398 // Ensure that the response stream is a web stream399 if (typeof body !== 'object' || !body || !('getReader' in body)) {400 this.#failConnection('Invalid response body, expected a web ReadableStream', status)401 this.close() // This should only happen if `fetch` provided is "faulty" - don't reconnect402 return403 }404 405 const decoder = new TextDecoder()406 407 const reader = body.getReader()408 let open = true409 410 do {411 const {done, value} = await reader.read()412 if (value) {413 this.#parser.feed(decoder.decode(value, {stream: !done}))414 }415 416 if (!done) {417 continue418 }419 420 open = false421 this.#parser.reset()422 423 this.#scheduleReconnect()424 } while (open)425 }426 427 /**428 * Handles rejected requests for the EventSource endpoint429 *430 * @param err - The error from `fetch()`431 * @internal432 */433 #onFetchError = (err: Error & {type?: string}) => {434 this.#controller = undefined435 436 // We expect abort errors when the user manually calls `close()` - ignore those437 if (err.name === 'AbortError' || err.type === 'aborted') {438 return439 }440 441 this.#scheduleReconnect(flattenError(err))442 }443 444 /**445 * Get request options for the `fetch()` request446 *447 * @returns The request options448 * @internal449 */450 #getRequestOptions(): EventSourceFetchInit {451 const lastEvent = this.#lastEventId ? {'Last-Event-ID': this.#lastEventId} : undefined452 453 const init: EventSourceFetchInit = {454 // [spec] Let `corsAttributeState` be `Anonymous`…455 // [spec] …will have their mode set to "cors"…456 mode: 'cors',457 redirect: 'follow',458 headers: {Accept: 'text/event-stream', ...lastEvent},459 cache: 'no-store',460 signal: this.#controller?.signal,461 }462 463 // Some environments crash if attempting to set `credentials` where it is not supported,464 // eg on Cloudflare Workers. To avoid this, we only set it in browser-like environments.465 if ('window' in globalThis) {466 // [spec] …and their credentials mode set to "same-origin"467 // [spec] …if the `withCredentials` attribute is `true`, set the credentials mode to "include"…468 init.credentials = this.withCredentials ? 'include' : 'same-origin'469 }470 471 return init472 }473 474 /**475 * Called by EventSourceParser instance when an event has successfully been parsed476 * and is ready to be processed.477 *478 * @param event - The parsed event479 * @internal480 */481 #onEvent = (event: EventSourceMessage) => {482 if (typeof event.id === 'string') {483 this.#lastEventId = event.id484 }485 486 const messageEvent = new MessageEvent(event.event || 'message', {487 data: event.data,488 origin: this.#redirectUrl ? this.#redirectUrl.origin : this.#url.origin,489 lastEventId: event.id || '',490 })491 492 // The `onmessage` property of the EventSource instance only triggers on messages without an493 // `event` field, or ones that explicitly set `message`.494 if (this.#onMessage && (!event.event || event.event === 'message')) {495 this.#onMessage(messageEvent)496 }497 498 this.dispatchEvent(messageEvent)499 }500 501 /**502 * Called by EventSourceParser instance when a new reconnection interval is received503 * from the EventSource endpoint.504 *505 * @param value - The new reconnection interval in milliseconds506 * @internal507 */508 #onRetryChange = (value: number) => {509 this.#reconnectInterval = value510 }511 512 /**513 * Handles the process referred to in the EventSource specification as "failing a connection".514 *515 * @param error - The error causing the connection to fail516 * @param code - The HTTP status code, if available517 * @internal518 */519 #failConnection(message?: string, code?: number) {520 // [spec] …if the readyState attribute is set to a value other than CLOSED,521 // [spec] sets the readyState attribute to CLOSED…522 if (this.#readyState !== this.CLOSED) {523 this.#readyState = this.CLOSED524 }525 526 // [spec] …and fires an event named `error` at the `EventSource` object.527 // [spec] Once the user agent has failed the connection, it does not attempt to reconnect.528 // [spec] > Implementations are especially encouraged to report detailed information529 // [spec] > to their development consoles whenever an error event is fired, since little530 // [spec] > to no information can be made available in the events themselves.531 // Printing to console is not very programatically helpful, though, so we emit a custom event.532 const errorEvent = new ErrorEvent('error', {code, message})533 534 this.#onError?.(errorEvent)535 this.dispatchEvent(errorEvent)536 }537 538 /**539 * Schedules a reconnection attempt against the EventSource endpoint.540 *541 * @param message - The error causing the connection to fail542 * @param code - The HTTP status code, if available543 * @internal544 */545 #scheduleReconnect(message?: string, code?: number) {546 // [spec] If the readyState attribute is set to CLOSED, abort the task.547 if (this.#readyState === this.CLOSED) {548 return549 }550 551 // [spec] Set the readyState attribute to CONNECTING.552 this.#readyState = this.CONNECTING553 554 // [spec] Fire an event named `error` at the EventSource object.555 const errorEvent = new ErrorEvent('error', {code, message})556 this.#onError?.(errorEvent)557 this.dispatchEvent(errorEvent)558 559 // [spec] Wait a delay equal to the reconnection time of the event source.560 this.#reconnectTimer = setTimeout(this.#reconnect, this.#reconnectInterval)561 }562 563 /**564 * Reconnects to the EventSource endpoint after a disconnect/failure565 *566 * @internal567 */568 #reconnect = () => {569 this.#reconnectTimer = undefined570 571 // [spec] If the EventSource's readyState attribute is not set to CONNECTING, then return.572 if (this.#readyState !== this.CONNECTING) {573 return574 }575 576 this.#connect()577 }578}579 580/**581 * According to spec, when constructing a URL:582 * > 1. Let baseURL be environment's base URL, if environment is a Document object583 * > 2. Return the result of applying the URL parser to url, with baseURL.584 *585 * Thus we should use `document.baseURI` if available, since it can be set through a base tag.586 *587 * @returns The base URL, if available - otherwise `undefined`588 * @internal589 */590function getBaseURL(): string | undefined {591 // eslint-disable-next-line @typescript-eslint/no-explicit-any592 const doc = 'document' in globalThis ? (globalThis as any).document : undefined593 return doc && typeof doc === 'object' && 'baseURI' in doc && typeof doc.baseURI === 'string'594 ? doc.baseURI595 : undefined596}597 