mahler
Version:
A automated task composer and HTN based planner for building autonomous system agents
112 lines • 4.32 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Agent = void 0;
const assert_1 = require("../assert");
const observable_1 = require("../observable");
const planner_1 = require("../planner");
const runtime_1 = require("./runtime");
const types_1 = require("./types");
const patch_1 = require("./patch");
__exportStar(require("./types"), exports);
__exportStar(require("./events"), exports);
function from({ initial: state, tasks = [], sensors = [], opts: userOpts = {}, planner = planner_1.Planner.from({
tasks,
}), }) {
const opts = {
maxRetries: Infinity,
follow: false,
plannerMaxWaitMs: 60 * 1000,
maxWaitMs: 5 * 60 * 1000,
minWaitMs: 1 * 1000,
backoffMs: (failures) => 2 ** failures * opts.minWaitMs,
strictIgnore: [],
...userOpts,
trace: userOpts.trace ?? (() => void 0),
};
(0, assert_1.default)(opts.maxRetries >= 0, 'opts.maxRetries must be greater than or equal to 0');
(0, assert_1.default)(opts.maxWaitMs > 0, 'opts.maxWaitMs must be greater than 0');
(0, assert_1.default)(opts.minWaitMs > 0, 'opts.minWaitMs must be greater than 0');
// Isolate the local state from the user input
state = structuredClone(state);
// Subscribe to runtime changes to keep
// the local copy of state up-to-date
const subject = new observable_1.Subject();
subject.subscribe((changes) => {
state = (0, patch_1.patch)(state, changes);
});
const observable = observable_1.Observable.from(subject).map(() => state);
let setupRuntime = Promise.resolve(null);
function seekInternal(target, strict) {
// We don't want seek to be an asynchronous call, so we
// wrap the runtime in a promise. This way, we can ensure
// that operations are always working on the right runtime,
// when the target changes or the agent is stopped
setupRuntime = setupRuntime.then((runtime) => {
// Flatten the promise chain to avoid memory leaks
setupRuntime = (async () => {
if (runtime != null) {
await runtime.stop();
state = runtime.state;
}
runtime = new runtime_1.Runtime(subject, state, target, planner, sensors, opts, strict);
runtime.start();
return runtime;
})();
return setupRuntime;
});
}
return {
seek(target) {
seekInternal(target, false);
},
seekStrict(target) {
seekInternal(target, true);
},
stop() {
void setupRuntime.then((runtime) => {
if (runtime == null) {
return;
}
// Reset the runtime
setupRuntime = Promise.resolve(null);
return runtime.stop().then(() => {
// We notify subscribers of completion only
// when stop is called
subject.complete();
});
});
},
async wait(timeout = 0) {
(0, assert_1.default)(timeout >= 0);
const runtime = await setupRuntime;
if (runtime == null) {
return { success: false, error: new types_1.NotStarted() };
}
return runtime.wait(timeout);
},
state() {
return state;
},
subscribe(next) {
return observable.subscribe(next);
},
};
}
exports.Agent = {
from,
};
//# sourceMappingURL=index.js.map