UNPKG

agents

Version:

A home for your AI agents

83 lines (82 loc) 2.42 kB
import { t as TextSegmentJoiner } from "./text-segment-joiner-BtAFQSA_.js"; //#region src/channels/stream.ts /** * Read a stream to completion, then finalize exactly once. * * `onFinish` runs whether the stream closed normally, errored because the * generation failed, or stopped because `onChunk` threw. A Channel that * finalizes here cannot lose a terminal provider call to an early ending. */ async function consumeChunks(chunks, consumer) { const reader = chunks.getReader(); let outcome = { interrupted: false }; let cancellation; try { while (true) { const { done, value } = await reader.read(); if (done) break; await consumer.onChunk(value); } } catch (error) { outcome = { interrupted: true, error }; cancellation = reader.cancel().catch(() => {}); } finally { reader.releaseLock(); } try { return await consumer.onFinish(outcome); } finally { await cancellation; } } /** * Collect every `text` chunk into one Markdown answer. * * The result reports interruption instead of throwing, because a Channel that * has partial text still has to decide what to deliver. */ function collectText(chunks) { let text = ""; const joiner = new TextSegmentJoiner(); return consumeChunks(chunks, { onChunk(chunk) { for (const event of joiner.pushChunk(chunk.type === "text" ? { type: "text-delta", text: chunk.text } : { type: chunk.type })) if (event.type === "text") text += event.text; }, onFinish: (outcome) => ({ text, interrupted: outcome.interrupted }) }); } /** * Pace repeated provider calls without dropping anything. * * A Channel accumulates into its own buffer and asks whether enough time has * passed to flush. Keeping the buffer in the Channel means an interrupted * stream leaves its tail in hand, ready for the terminal provider call, rather * than stranded inside a transform. */ function createPacer(intervalMs) { let lastFlushAt = Number.NEGATIVE_INFINITY; return () => { const now = Date.now(); if (now - lastFlushAt < intervalMs) return false; lastFlushAt = now; return true; }; } //#endregion //#region src/channels/ingress.ts /** Match an HTTP request to one exact URL pathname. */ function matchesPath(request, path) { return new URL(request.url).pathname === path; } //#endregion export { createPacer as i, collectText as n, consumeChunks as r, matchesPath as t }; //# sourceMappingURL=ingress-BfetZbMO.js.map