@openai/agents-core
Version:
The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows.
95 lines • 3.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.setAgentToolStreamBuffer = setAgentToolStreamBuffer;
exports.getAgentToolStreamBuffer = getAgentToolStreamBuffer;
exports.createAgentToolStreamBuffer = createAgentToolStreamBuffer;
exports.drainAgentToolStream = drainAgentToolStream;
const errors_1 = require("../errors.js");
const runnerStreamBuffers = new WeakMap();
function setAgentToolStreamBuffer(runner, buffer) {
runnerStreamBuffers.set(runner, buffer);
}
function getAgentToolStreamBuffer(runner) {
return runnerStreamBuffers.get(runner);
}
function createAgentToolStreamBuffer(maxPendingEvents, controller) {
return {
maxPendingEvents,
overflow() {
const error = new errors_1.UserError(`Agent tool stream backlog exceeded onStreamMaxPendingEvents=${maxPendingEvents}. ` +
'Use faster handlers, increase the limit, or set it to null.');
controller.abort(error);
throw error;
},
};
}
// Remove the abort listener after each dispatch rather than accumulating races
// against a single promise for the lifetime of a potentially long stream.
async function waitForHandlers(handlers, signal) {
let onAbort = () => { };
const aborted = new Promise((resolve) => {
onAbort = resolve;
if (signal.aborted) {
resolve();
}
else {
signal.addEventListener('abort', onAbort, { once: true });
}
});
try {
await Promise.race([handlers, aborted]);
}
finally {
signal.removeEventListener('abort', onAbort);
}
}
async function drainAgentToolStream(result, emit, signal, controller) {
// A failed producer must also release a dispatch blocked on an observer.
void result.completed.catch((error) => controller.abort(error));
const iterator = result[Symbol.asyncIterator]();
let failed = false;
let failure;
const recordFailure = (error) => {
if (!failed) {
failed = true;
failure = error;
}
};
try {
while (!signal.aborted) {
const next = await iterator.next();
if (next.done || signal.aborted) {
break;
}
await waitForHandlers(emit(next.value), signal);
}
}
catch (error) {
recordFailure(error);
}
finally {
// Explicitly close even when next() rejected, and wait for producer cleanup
// without waiting for an application callback that cannot be cancelled.
try {
await iterator.return?.();
}
catch (error) {
recordFailure(error);
}
try {
await result.completed;
}
catch (error) {
recordFailure(error);
}
}
// Internal failure is recorded before aborting. Cleanup cannot replace it.
if (controller.signal.aborted && signal.reason === controller.signal.reason) {
throw controller.signal.reason;
}
if (failed) {
signal.throwIfAborted();
throw failure;
}
}
//# sourceMappingURL=agentToolStream.js.map