assistant-stream
Version:
Streaming utilities for AI assistants
100 lines (99 loc) • 3.25 kB
JavaScript
import { NO_RESULT } from "../tool/ToolResponse.js";
import { createControllerStream, createControllerStreamPair } from "../utils/stream/createControllerStream.js";
import { closeIfOpen, enqueueIfOpen } from "../utils/stream/controller-guards.js";
import { TextStreamControllerImpl } from "./text.js";
// src/core/modules/tool-call.ts
var ToolCallStreamControllerImpl = class {
_isClosed = false;
_hasArgsText = false;
_argsTextState = "open";
_controller;
_argsTextController;
_options;
constructor(_controller, options = {}) {
this._controller = _controller;
this._options = options;
this._argsTextController = new TextStreamControllerImpl({
enqueue: (chunk) => {
if (this._argsTextState !== "open") throw new TypeError("Cannot append to finished tool-call args");
if (chunk.type === "text-delta") {
this._hasArgsText = true;
this._controller.enqueue(chunk);
return;
}
this._argsTextState = "finishing";
queueMicrotask(() => this._finishArgsText());
},
close: () => {}
}, { strict: this._options.strict });
}
_finishArgsText() {
if (this._argsTextState !== "finishing") return;
this._argsTextState = "finished";
if (!this._hasArgsText) enqueueIfOpen(this._controller, {
type: "text-delta",
textDelta: "{}",
path: []
});
enqueueIfOpen(this._controller, {
type: "tool-call-args-text-finish",
path: []
});
}
get argsText() {
return this._argsTextController;
}
async setResponse(response) {
if (this._isClosed) return;
const result = response.result;
enqueueIfOpen(this._controller, {
type: "result",
path: [],
...response.artifact !== void 0 ? { artifact: response.artifact } : {},
result: result === void 0 ? NO_RESULT : result,
isError: response.isError ?? false,
...response.isPreliminary ? { isPreliminary: true } : {},
...response.modelContent !== void 0 ? { modelContent: response.modelContent } : {},
...response.messages !== void 0 ? { messages: response.messages } : {}
});
if (response.isPreliminary) {
this._argsTextController.close();
this._finishArgsText();
} else await this.close();
}
setApproval(approval) {
enqueueIfOpen(this._controller, {
type: "tool-call-approval",
path: [],
approval
});
}
async close() {
if (this._isClosed) return;
this._isClosed = true;
this._options.onClose?.();
this._argsTextController.close();
this._finishArgsText();
enqueueIfOpen(this._controller, {
type: "part-finish",
path: []
});
closeIfOpen(this._controller);
}
__internal_truncate() {
if (this._isClosed) return;
this._isClosed = true;
this._finishArgsText();
this._argsTextController.__internal_truncate();
this._argsTextState = "finished";
closeIfOpen(this._controller);
}
};
const createToolCallStream = (readable, options = {}) => {
return createControllerStream(readable, (controller) => new ToolCallStreamControllerImpl(controller, options));
};
const createToolCallStreamController = (options = {}) => {
return createControllerStreamPair((controller) => new ToolCallStreamControllerImpl(controller, options));
};
export { ToolCallStreamControllerImpl, createToolCallStream, createToolCallStreamController };
//# sourceMappingURL=tool-call.js.map