UNPKG

life

Version:

Life.js is the first fullstack framework to build agentic web applications. It is minimal, extensible, and typesafe. Well, everything you love.

351 lines (328 loc) 12.3 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _chunkSDCJCCXNjs = require('../chunk-SDCJCCXN.js'); require('../chunk-EL6AAGQA.js'); require('../chunk-W2LGDDT2.js'); require('../chunk-FID44QSN.js'); require('../chunk-VLUR4YND.js'); var _chunkOTBM3PZSjs = require('../chunk-OTBM3PZS.js'); var _chunkBFC2WP6Qjs = require('../chunk-BFC2WP6Q.js'); require('../chunk-22H3U7VV.js'); var _chunk6PEHRAEPjs = require('../chunk-6PEHRAEP.js'); // agent/client/builder.ts var AgentClientBuilder = class _AgentClientBuilder { static { _chunk6PEHRAEPjs.__name.call(void 0, this, "AgentClientBuilder"); } constructor(definition) { this.def = definition; } /** * Register plugins to extend the agent client features. * Defaults to `[generation, memories, stores, actions, percepts]` plugins if not specified. * * In case you want to register custom plugins and still keep the defaults you can do: * ```ts * import { defaults } from "life/server"; * * defineAgent("my-agent").plugins([...defaults.plugins, myCustomPlugin]); * ``` * * Or if you want only some of the defaults, you can do: * ```ts * import { defaults } from "life/server"; * * defineAgent("my-agent").plugins([defaults.plugins.generation, defaults.plugins.memories]); * ``` */ plugins(plugins) { const builder = new _AgentClientBuilder({ ...this.def, plugins: plugins.map((p) => p.def) }); const builderWithPlugins = _AgentClientBuilder.withPluginsMethods(builder); return builderWithPlugins; } // biome-ignore lint/suspicious/noExplicitAny: reason static withPluginsMethods(builder) { for (const plugin of builder.def.plugins) { Object.assign(builder, { [_chunkOTBM3PZSjs.toMethodName.call(void 0, plugin.name)]: (config) => { const newBuilder = new _AgentClientBuilder({ ...builder.def, pluginConfigs: { ..._nullishCoalesce(builder.def.pluginConfigs, () => ( {})), [plugin.name]: config } }); return _AgentClientBuilder.withPluginsMethods(newBuilder); } }); } return builder; } }; function defineAgentClient(name) { const defaultDefinition = { name, plugins: [...defaults.plugins].map((p) => p.def), pluginConfigs: {}, $serverDef: {} }; const builder = new AgentClientBuilder(defaultDefinition); const builderWithPlugins = AgentClientBuilder.withPluginsMethods(builder); return builderWithPlugins; } _chunk6PEHRAEPjs.__name.call(void 0, defineAgentClient, "defineAgentClient"); // plugins/client/builder.ts var _zod = require('zod'); var _zod2 = _interopRequireDefault(_zod); var PluginClientBuilder = class _PluginClientBuilder { static { _chunk6PEHRAEPjs.__name.call(void 0, this, "PluginClientBuilder"); } constructor(definition) { this.def = definition; } /** * ### `.dependencies()` * * Specify other plugins clients as required by this plugin client. * * Their config, atoms, and class can then be accessed from `dependencies.*` inside the plugin client's class and atoms. * * @see TODO: Add docs link * * @example * ```ts * const pluginClient = definePluginClient("my-plugin") * .dependencies([anotherPluginClient]) * .atoms(({ dependencies }) => { * // Obtain the atoms of the dependency plugin client * const anotherPluginAtoms = dependencies.anotherPlugin.atoms(); * // ... * }); * ``` * &nbsp; * * --- * @param plugins - The dependencies definitions. * @returns TypedPluginClientBuilder */ dependencies(plugins) { const dependencies = plugins.map((p) => p.def); const builder = new _PluginClientBuilder({ ...this.def, dependencies }); return builder; } /** * ### `.config()` * * Add a configuration that users can provide to tweak plugin client's behavior. * * @see TODO: Add docs link * * @example * ```ts * const myPluginClient = definePluginClient("my-plugin") * .config({ schema: z.object({ refreshRate: z.number() }) }); * * const myAgentClient = defineAgentClient("my-agent") * .plugins([myPluginClient]) * .myPlugin({ refreshRate: 1000 }); // <-- Here * ``` * &nbsp; * * --- * * The provided config can then be accessed from `plugin.config` inside atoms and class. * * @example * ```ts * const pluginClient = definePluginClient("my-plugin") * .config({ schema: z.object({ refreshRate: z.number() }) }); * .atoms(({ config }) => { * const refreshRate = config.refreshRate; // <-- Here * }); * ``` * &nbsp; * * --- * @param config - The config definition. * @returns TypedPluginClientBuilder */ config(config) { return this.$config(_chunkBFC2WP6Qjs.zodObjectWithTelemetry.call(void 0, config)); } /** * ### `.$config()` * * Define plugin client config from the output of `definePluginClientConfig()`. * * @see TODO: Add docs link for `definePluginClientConfig()` * * --- * @param config - The config definition. * @returns TypedPluginClientBuilder */ $config(config) { const builder = new _PluginClientBuilder({ ...this.def, config }); return builder; } /** * ### `.class()` * * TODO * * @see TODO: Add docs link * * --- * @param input - The class definition. * @returns TypedPluginClientBuilder */ class(extension) { const builder = new _PluginClientBuilder({ ...this.def, class: extension }); return builder; } /** * ### `.atoms()` * * Add reactive states (atoms) that can then be consumed from various UI frameworks * (React, Vue, Svelte, etc.) to render the plugin data in real-time on the user interface. * * Atoms are powered by [nanostores](https://github.com/nanostores/nanostores). * * @see TODO: Add docs link * * @example * ```ts * import { onMount } from "nanostores"; * * const pluginClient = definePluginClient("my-plugin") * .atoms(({ plugin }) => { * const value = atom(0); * onMount(() => { * setInterval(async () => { * const context = await plugin.context.get(); * value.set(context.value + 1); * }, 1000); * }); * return { value }; * }); * ``` * &nbsp; * * --- * * Then from a React component, you can render the `value` atom: * ```ts * import { useStore } from "nanostores/react"; * * export default function Page() { * const agent = useAgent("my-agent"); * const value = useStore(agent.myPlugin.atoms.value); * return <div>{value}</div>; * }; * ``` * &nbsp; * * --- * @param definition - The atoms definition. * @returns TypedPluginClientBuilder */ atoms(atoms) { const builder = new _PluginClientBuilder({ ...this.def, atoms }); return builder; } }; function definePluginClient(name) { const defaultDefinition = { name, config: _chunkBFC2WP6Qjs.zodObjectWithTelemetry.call(void 0, { schema: _zod.z.object() }), dependencies: [], class: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (..._args) => class { }, "class"), atoms: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (..._args) => [], "atoms"), $serverDef: null }; return new PluginClientBuilder(defaultDefinition); } _chunk6PEHRAEPjs.__name.call(void 0, definePluginClient, "definePluginClient"); // plugins/defaults/generation/client.ts var _nanostores = require('nanostores'); var generationPluginClient = definePluginClient("generation").config({ schema: _zod2.default.object({ enableVoice: _zod2.default.boolean().prefault(false) }) }).class( ({ plugin }) => (_class = class {constructor() { _class.prototype.__init.call(this); } async continue(params) { return await plugin.server.events.emit({ name: "agent.continue", data: params }); } async decide(params) { return await plugin.server.events.emit({ name: "agent.decide", data: params }); } async say(params) { return await plugin.server.events.emit({ name: "agent.say", data: params }); } async interrupt(params) { return await plugin.server.events.emit({ name: "agent.interrupt", data: params }); } __init() {this.messages = { create: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, async (params) => await plugin.server.events.emit({ name: "messages.create", data: params }), "create"), update: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, async (params) => await plugin.server.events.emit({ name: "messages.update", data: params }), "update"), get: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, () => plugin.server.context.get().messages, "get") }} }, _class) ).atoms(({ plugin, telemetry }) => [ { name: "status", create: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, () => { const store = _nanostores.atom.call(void 0, null); _nanostores.onMount.call(void 0, store, () => { const [error, context] = plugin.server.context.safe.get(); if (error) telemetry.log.error({ message: "Failed to fetch initial status from context.", error }); if (_optionalChain([context, 'optionalAccess', _2 => _2.status])) store.set(context.status); const unsubscribe = plugin.server.context.onChange( (ctx) => ctx.status, (ctx) => store.set(ctx.status) ); return () => _optionalChain([unsubscribe, 'optionalCall', _3 => _3()]); }); return { store, refresh: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, async () => void 0, "refresh") }; }, "create") }, { name: "messages", create: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, () => { const store = _nanostores.atom.call(void 0, []); _nanostores.onMount.call(void 0, store, () => { const [error, context] = plugin.server.context.safe.get(); if (error) telemetry.log.error({ message: "Failed to fetch initial messages from context.", error }); if (_optionalChain([context, 'optionalAccess', _4 => _4.messages])) store.set(context.messages); const unsubscribe = plugin.server.context.onChange( (ctx) => ctx.messages, (ctx) => store.set(ctx.messages) ); return () => _optionalChain([unsubscribe, 'optionalCall', _5 => _5()]); }); return { store, refresh: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, async () => void 0, "refresh") }; }, "create") } ]); // plugins/defaults/memories/client.ts var memoriesPluginClient = definePluginClient("memories").dependencies([generationPluginClient]).class((_) => class { }); // plugins/defaults/stores/client.ts var storesPluginClient = definePluginClient("stores"); // exports/client.ts var defaults = { plugins: { generation: generationPluginClient, memories: memoriesPluginClient, stores: storesPluginClient, *[Symbol.iterator]() { for (const entry of Object.values(this)) yield entry; } } }; exports.createLifeClient = _chunkSDCJCCXNjs.createLifeClient; exports.defaults = defaults; exports.defineAgentClient = defineAgentClient; exports.definePluginClient = definePluginClient; exports.parseAgentClientParam = _chunkSDCJCCXNjs.parseAgentClientParam; //# sourceMappingURL=client.js.map