assistan-ts
Version:
A typesafe and code-first library to define and run OpenAI assistants
111 lines • 5.3 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.waitForRequiredAction = exports.waitForComplete = void 0;
// TOOD: Rewrite
const waitForComplete = (run, params, timeout) => __awaiter(void 0, void 0, void 0, function* () {
const start = Date.now();
run = yield poll(run, params, timeout);
// handle all actions
if (run.status === "requires_action" && run.required_action) {
run = yield runAndSubmitTools(run, params);
const newTimeout = timeout ? timeout - (Date.now() - start) : undefined;
if (newTimeout && newTimeout <= 0) {
return run;
}
return yield (0, exports.waitForComplete)(run, params, newTimeout);
}
return run;
});
exports.waitForComplete = waitForComplete;
const waitForRequiredAction = (run, params, timeout) => __awaiter(void 0, void 0, void 0, function* () {
run = yield poll(run, params, timeout);
// handle all actions
if (run.status === "requires_action" && run.required_action) {
return {
run,
toolsRequest: {
toolCalls: run.required_action.submit_tool_outputs.tool_calls,
execute: (responseOverrides) => __awaiter(void 0, void 0, void 0, function* () {
run = yield runAndSubmitTools(run, params, responseOverrides);
return yield (0, exports.waitForRequiredAction)(run, params);
}),
},
};
}
return { run, toolsRequest: null };
});
exports.waitForRequiredAction = waitForRequiredAction;
function runAndSubmitTools(run, params, responseOverrides = {}) {
var _a, _b, _c, _d;
return __awaiter(this, void 0, void 0, function* () {
const { toolbox, openai, abortSignal, onStatusChange } = params;
let status = run.status;
const toolCalls = (_b = (_a = run.required_action) === null || _a === void 0 ? void 0 : _a.submit_tool_outputs.tool_calls) !== null && _b !== void 0 ? _b : [];
const overrides = (_c = toolCalls
.filter((it) => responseOverrides[it.id] !== undefined)
.map((it) => ({
tool_call_id: it.id,
output: responseOverrides[it.id],
}))) !== null && _c !== void 0 ? _c : [];
const toolPromises = (_d = toolCalls
.filter((it) => responseOverrides[it.id] === undefined)
.map((toolCall) => toolbox.handleAction(toolCall).catch((e) => e))) !== null && _d !== void 0 ? _d : [];
// TODO: Should we catch error and submit successes?
const { resolved, rejected } = (yield Promise.all(toolPromises)).reduce((acc, cur) => {
if (cur instanceof Error) {
acc.rejected.push(cur);
}
else {
acc.resolved.push(cur);
}
return acc;
}, { resolved: [], rejected: [] });
const tool_outputs = [...overrides, ...resolved];
if (tool_outputs.length) {
run = yield openai.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {
tool_outputs,
}, { signal: abortSignal });
if (run.status !== status) {
onStatusChange === null || onStatusChange === void 0 ? void 0 : onStatusChange(run, status);
status = run.status;
}
}
if (rejected.length > 0) {
//TODO: throw multiple errors?
throw rejected[0];
}
return run;
});
}
function poll(run, params, timeout) {
return __awaiter(this, void 0, void 0, function* () {
const { openai, interval = 1000, abortSignal, onStatusChange } = params;
let status = run.status;
// note: this timeout does not include the processing time, and thus could exceed the supplied value!
let remainingTime = timeout !== null && timeout !== void 0 ? timeout : Infinity;
while ((run.status === "queued" || run.status === "in_progress") &&
remainingTime > 0) {
const start = Date.now();
yield new Promise((resolve) => setTimeout(resolve, Math.min(remainingTime, interval)));
run = yield openai.beta.threads.runs.retrieve(run.thread_id, run.id, {
signal: abortSignal,
});
if (run.status !== status) {
onStatusChange === null || onStatusChange === void 0 ? void 0 : onStatusChange(run, status);
status = run.status;
}
remainingTime -= Date.now() - start;
}
return run;
});
}
//# sourceMappingURL=run.js.map