@langchain/langgraph
Version:
LangGraph
147 lines • 5.35 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChannelWrite = exports.PASSTHROUGH = exports.SKIP_WRITE = void 0;
const runnables_1 = require("@langchain/core/runnables");
const constants_js_1 = require("../constants.cjs");
const utils_js_1 = require("../utils.cjs");
const errors_js_1 = require("../errors.cjs");
exports.SKIP_WRITE = {
[Symbol.for("LG_SKIP_WRITE")]: true,
};
function _isSkipWrite(x) {
return (typeof x === "object" &&
// eslint-disable-next-line @typescript-eslint/no-explicit-any
x?.[Symbol.for("LG_SKIP_WRITE")] !== undefined);
}
exports.PASSTHROUGH = {
[Symbol.for("LG_PASSTHROUGH")]: true,
};
function _isPassthrough(x) {
return (typeof x === "object" &&
// eslint-disable-next-line @typescript-eslint/no-explicit-any
x?.[Symbol.for("LG_PASSTHROUGH")] !== undefined);
}
const IS_WRITER = Symbol("IS_WRITER");
/**
* Mapping of write channels to Runnables that return the value to be written,
* or None to skip writing.
*/
class ChannelWrite extends utils_js_1.RunnableCallable {
constructor(writes, tags) {
const name = `ChannelWrite<${writes
.map((packet) => {
if ((0, constants_js_1._isSend)(packet)) {
return packet.node;
}
else if ("channel" in packet) {
return packet.channel;
}
return "...";
})
.join(",")}>`;
super({
...{ writes, name, tags },
func: async (input, config) => {
return this._write(input, config ?? {});
},
});
Object.defineProperty(this, "writes", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.writes = writes;
}
async _write(input, config) {
const writes = this.writes.map((write) => {
if (_isChannelWriteTupleEntry(write) && _isPassthrough(write.value)) {
return {
mapper: write.mapper,
value: input,
};
}
else if (_isChannelWriteEntry(write) && _isPassthrough(write.value)) {
return {
channel: write.channel,
value: input,
skipNone: write.skipNone,
mapper: write.mapper,
};
}
else {
return write;
}
});
await ChannelWrite.doWrite(config, writes);
return input;
}
// TODO: Support requireAtLeastOneOf
static async doWrite(config, writes) {
// validate
for (const w of writes) {
if (_isChannelWriteEntry(w)) {
if (w.channel === constants_js_1.TASKS) {
throw new errors_js_1.InvalidUpdateError("Cannot write to the reserved channel TASKS");
}
if (_isPassthrough(w.value)) {
throw new errors_js_1.InvalidUpdateError("PASSTHROUGH value must be replaced");
}
}
if (_isChannelWriteTupleEntry(w)) {
if (_isPassthrough(w.value)) {
throw new errors_js_1.InvalidUpdateError("PASSTHROUGH value must be replaced");
}
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const writeEntries = [];
for (const w of writes) {
if ((0, constants_js_1._isSend)(w)) {
writeEntries.push([constants_js_1.TASKS, w]);
}
else if (_isChannelWriteTupleEntry(w)) {
const mappedResult = await w.mapper.invoke(w.value, config);
if (mappedResult != null && mappedResult.length > 0) {
writeEntries.push(...mappedResult);
}
}
else if (_isChannelWriteEntry(w)) {
const mappedValue = w.mapper !== undefined
? await w.mapper.invoke(w.value, config)
: w.value;
if (_isSkipWrite(mappedValue)) {
continue;
}
if (w.skipNone && mappedValue === undefined) {
continue;
}
writeEntries.push([w.channel, mappedValue]);
}
else {
throw new Error(`Invalid write entry: ${JSON.stringify(w)}`);
}
}
const write = config.configurable?.[constants_js_1.CONFIG_KEY_SEND];
write(writeEntries);
}
static isWriter(runnable) {
return (
// eslint-disable-next-line no-instanceof/no-instanceof
runnable instanceof ChannelWrite ||
(IS_WRITER in runnable && !!runnable[IS_WRITER]));
}
static registerWriter(runnable) {
return Object.defineProperty(runnable, IS_WRITER, { value: true });
}
}
exports.ChannelWrite = ChannelWrite;
function _isChannelWriteEntry(x) {
return (x !== undefined && typeof x.channel === "string");
}
function _isChannelWriteTupleEntry(x) {
return (x !== undefined &&
!_isChannelWriteEntry(x) &&
runnables_1.Runnable.isRunnable(x.mapper));
}
//# sourceMappingURL=write.js.map
;