assistant-stream
Version:
Streaming utilities for AI assistants
88 lines (72 loc) • 2.33 kB
text/typescript
import type { ReadonlyJSONValue } from "../../utils";
import { createControllerStreamPair } from "../utils/stream/createControllerStream";
import { withPromiseOrValue } from "../utils/withPromiseOrValue";
import { GorpStreamAccumulator } from "./GorpStreamAccumulator";
import type { GorpStreamOperation, GorpStreamChunk } from "./types";
type GorpStreamController = {
readonly abortSignal: AbortSignal;
enqueue(operations: readonly GorpStreamOperation[]): void;
};
class GorpStreamControllerImpl implements GorpStreamController {
private _controller: ReadableStreamDefaultController<GorpStreamChunk>;
private _abortController = new AbortController();
private _accumulator: GorpStreamAccumulator;
private _cancelled = false;
get abortSignal() {
return this._abortController.signal;
}
constructor(
controller: ReadableStreamDefaultController<GorpStreamChunk>,
defaultValue: ReadonlyJSONValue,
) {
this._controller = controller;
this._accumulator = new GorpStreamAccumulator(defaultValue);
}
enqueue(operations: readonly GorpStreamOperation[]) {
if (this._cancelled) return;
this._accumulator.append(operations);
this._controller.enqueue({
snapshot: this._accumulator.state,
operations,
});
}
__internalError(error: unknown) {
if (this._cancelled) return;
this._controller.error(error);
}
__internalClose() {
if (this._cancelled) return;
this._controller.close();
}
__internalCancel(reason?: unknown) {
this._cancelled = true;
this._abortController.abort(reason);
}
}
type CreateGorpStreamOptions = {
execute: (controller: GorpStreamController) => void | PromiseLike<void>;
defaultValue?: ReadonlyJSONValue;
};
export const createGorpStream = ({
execute,
defaultValue = {},
}: CreateGorpStreamOptions) => {
const [stream, controller] = createControllerStreamPair<
GorpStreamChunk,
GorpStreamControllerImpl
>(
(streamController) =>
new GorpStreamControllerImpl(streamController, defaultValue),
(streamController, reason) => streamController.__internalCancel(reason),
);
withPromiseOrValue(
() => execute(controller),
() => {
controller.__internalClose();
},
(e: unknown) => {
controller.__internalError(e);
},
);
return stream;
};