life
Version:
Life.js is the first fullstack framework to build agentic web applications. It is minimal, extensible, and typesafe. Well, everything you love.
1,198 lines (1,142 loc) • 48 kB
JavaScript
;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(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await 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 _chunkEL6AAGQAjs = require('./chunk-EL6AAGQA.js');
var _chunkW2LGDDT2js = require('./chunk-W2LGDDT2.js');
var _chunkFID44QSNjs = require('./chunk-FID44QSN.js');
var _chunkVLUR4YNDjs = require('./chunk-VLUR4YND.js');
var _chunkOTBM3PZSjs = require('./chunk-OTBM3PZS.js');
var _chunkBFC2WP6Qjs = require('./chunk-BFC2WP6Q.js');
var _chunk22H3U7VVjs = require('./chunk-22H3U7VV.js');
var _chunk6PEHRAEPjs = require('./chunk-6PEHRAEP.js');
// shared/hmr.ts
var rawHMR = (
// - Vite / Bun / modern dev servers
typeof import.meta !== "undefined" && import.meta.hot || // - Webpack ESM
typeof import.meta !== "undefined" && import.meta.webpackHot || // - Webpack CJS
_optionalChain([globalThis, 'optionalAccess', _ => _.module, 'optionalAccess', _2 => _2.hot]) || // - None
null
);
var hmr = Object.freeze(
rawHMR ? {
active: true,
accept: rawHMR.accept ? (...args) => _optionalChain([rawHMR, 'access', _3 => _3.accept, 'optionalCall', _4 => _4(...args)]) : void 0,
dispose: rawHMR.dispose || rawHMR.addDisposeHandler ? (cb) => _optionalChain([(rawHMR.dispose || rawHMR.addDisposeHandler), 'optionalCall', _5 => _5(cb)]) : void 0
} : { active: false }
);
// plugins/client/class.ts
var _zod = require('zod'); var _zod2 = _interopRequireDefault(_zod);
var PluginClient = class {
static {
_chunk6PEHRAEPjs.__name.call(void 0, this, "PluginClient");
}
#config;
#agent;
#telemetry;
#atoms;
#extension;
#eventsListeners = /* @__PURE__ */ new Map();
#contextListeners = /* @__PURE__ */ new Map();
#contextValue = {};
#lastContextValueTimestamp = 0;
constructor(definition, config, agent) {
this.def = definition;
this.#agent = agent;
const { error: errConfig, data: parsedConfig } = this.def.config.schema.safeParse(config);
if (errConfig) {
throw _chunk22H3U7VVjs.lifeError.call(void 0, {
code: "Validation",
message: `Invalid config provided to plugin client '${this.def.name}'.`,
cause: errConfig
});
}
this.#config = parsedConfig;
this.#telemetry = _chunkEL6AAGQAjs.createTelemetryClient.call(void 0, "plugin.client", {
agentId: agent.id,
agentName: agent.def.name,
agentConfig: agent.config,
transportProviderName: agent.config.transport.provider,
pluginName: definition.name,
pluginClientConfig: this.#config
});
const [errAccessor, accessor] = this.getAccessor();
if (errAccessor) throw errAccessor;
this.#extension = new (definition.class({
plugin: _chunk22H3U7VVjs.toPublic.call(void 0, accessor),
agent: _chunk22H3U7VVjs.toPublic.call(void 0, this.#agent),
dependencies: this.getDependenciesAccessor(),
telemetry: this.#telemetry
}))();
const atomsArr = definition.atoms({
plugin: _chunk22H3U7VVjs.toPublic.call(void 0, accessor),
agent: _chunk22H3U7VVjs.toPublic.call(void 0, this.#agent),
dependencies: this.getDependenciesAccessor(),
telemetry: this.#telemetry
});
const atomsMap = Object.fromEntries(atomsArr.map((atom2) => [atom2.name, atom2.create]));
this.#atoms = atomsMap;
}
getAccessor() {
const [errClone, cloneConfig] = _chunk22H3U7VVjs.attempt.call(void 0, () => _chunkBFC2WP6Qjs.deepClone.call(void 0, this.#config));
if (errClone) return _chunk22H3U7VVjs.failure.call(void 0, { code: "Unknown", cause: errClone });
const serverContextGet = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (() => _chunk22H3U7VVjs.attempt.call(void 0, () => _chunkBFC2WP6Qjs.deepClone.call(void 0, this.#contextValue))), "serverContextGet");
const serverContextOnChange = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, ((selector, callback) => {
const id = _chunk22H3U7VVjs.newId.call(void 0, "listener");
this.#contextListeners.set(id, { id, callback, selector });
return _chunk22H3U7VVjs.success.call(void 0, () => this.#contextListeners.delete(id));
}), "serverContextOnChange");
const serverEventsEmit = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (async (event) => {
const [err, data] = await this.#agent.transport.call({
name: `plugin.${this.def.name}.events.emit`,
schema: {
input: _chunkOTBM3PZSjs.pluginEventInputSchema,
output: _zod2.default.object({ id: _zod2.default.string() })
},
input: event
});
if (err) return _chunk22H3U7VVjs.failure.call(void 0, err);
return _chunk22H3U7VVjs.success.call(void 0, data.id);
}), "serverEventsEmit");
const serverEventsOn = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, ((selector, callback, includeDropped = false) => {
const id = _chunk22H3U7VVjs.newId.call(void 0, "listener");
this.#eventsListeners.set(id, { id, selector, callback, includeDropped });
this.#agent.transport.call({
name: `plugin.${this.def.name}.events.subscribe`,
schema: {
input: _zod2.default.object({
listenerId: _zod2.default.string(),
selector: _zod2.default.any(),
includeDropped: _zod2.default.boolean().prefault(false)
})
},
input: { listenerId: id, selector, includeDropped }
});
return _chunk22H3U7VVjs.success.call(void 0, () => {
this.#agent.transport.call({
name: `plugin.${this.def.name}.events.unsubscribe`,
schema: { input: _zod2.default.object({ listenerId: _zod2.default.string() }) },
input: { listenerId: id }
});
this.#eventsListeners.delete(id);
});
}), "serverEventsOn");
const serverEventsOnce = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, ((selector, callback, includeDropped = false) => {
const [errOn, unsubscribe] = serverEventsOn(
selector,
async (event) => {
_optionalChain([unsubscribe, 'optionalCall', _6 => _6()]);
await callback(event);
},
includeDropped
);
if (errOn) return _chunk22H3U7VVjs.failure.call(void 0, errOn);
return _chunk22H3U7VVjs.success.call(void 0, unsubscribe);
}), "serverEventsOnce");
const serverEventsWaitForProcessing = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (async (eventId) => await this.#agent.transport.call({
name: `plugin.${this.def.name}.events.waitForProcessing`,
schema: { input: _zod2.default.object({ eventId: _zod2.default.string() }) },
input: { eventId }
})), "serverEventsWaitForProcessing");
const serverEventsWaitForResult = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (async (eventId, handlerName) => (
// @ts-expect-error
await this.#agent.transport.call({
name: `plugin.${this.def.name}.events.waitForResult`,
schema: {
input: _zod2.default.object({ eventId: _zod2.default.string(), handlerName: _zod2.default.string() }),
output: _zod2.default.object().loose()
},
input: { eventId, handlerName }
})
)), "serverEventsWaitForResult");
return _chunk22H3U7VVjs.success.call(void 0,
Object.assign(_nullishCoalesce(this.#extension, () => ( {})), {
config: cloneConfig,
atoms: this.#atoms,
server: {
context: {
onChange: serverContextOnChange,
get: serverContextGet
},
events: {
emit: serverEventsEmit,
on: serverEventsOn,
once: serverEventsOnce,
waitForProcessing: serverEventsWaitForProcessing,
waitForResult: serverEventsWaitForResult
}
}
})
);
}
getDependenciesAccessor() {
const dependenciesAccessors = {};
for (const dependencyDef of _nullishCoalesce(this.def.dependencies, () => ( []))) {
const accessor = this.#agent[_chunkOTBM3PZSjs.toMethodName.call(void 0, dependencyDef.name)];
if (!accessor)
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "NotFound",
message: `Failed to obtain client instance for dependency plugin '${dependencyDef.name}'. Shouldn't happen.`
});
dependenciesAccessors[dependencyDef.name] = accessor;
}
return _chunk22H3U7VVjs.success.call(void 0, dependenciesAccessors);
}
async start() {
const [errPing, dataPing] = await this.#agent.transport.call({
name: "agent.has-plugin-server",
schema: {
input: _zod2.default.object({ pluginName: _zod2.default.string() }),
output: _zod2.default.object({
hasServer: _zod2.default.boolean()
})
},
input: { pluginName: this.def.name }
});
if (errPing) return _chunk22H3U7VVjs.failure.call(void 0, errPing);
if (!dataPing.hasServer) return _chunk22H3U7VVjs.success.call(void 0, );
this.#agent.transport.register({
name: `plugin.${this.def.name}.context.changed`,
schema: { input: _zod2.default.object({ value: _zod2.default.any(), timestamp: _zod2.default.number() }) },
execute: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, async ({ value, timestamp }) => await this.#setContextValue(value, timestamp), "execute")
});
this.#agent.transport.register({
name: `plugin.${this.def.name}.events.callback`,
schema: {
input: _zod2.default.object({ listenerId: _zod2.default.string(), event: _chunkOTBM3PZSjs.pluginEventInputSchema })
},
execute: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, async ({ listenerId, event }) => {
await _optionalChain([this, 'access', _7 => _7.#eventsListeners, 'access', _8 => _8.get, 'call', _9 => _9(listenerId), 'optionalAccess', _10 => _10.callback, 'call', _11 => _11(event)]);
return _chunk22H3U7VVjs.success.call(void 0, );
}, "execute")
});
const [err, data] = await this.#agent.transport.call({
name: `plugin.${this.def.name}.context.get`,
schema: { output: _zod2.default.object({ value: _zod2.default.any(), timestamp: _zod2.default.number() }) }
});
if (err) return _chunk22H3U7VVjs.failure.call(void 0, err);
return await this.#setContextValue(data.value, data.timestamp);
}
async #setContextValue(value, timestamp) {
const oldContextValue = _chunkBFC2WP6Qjs.deepClone.call(void 0, this.#contextValue);
if (timestamp < this.#lastContextValueTimestamp) return _chunk22H3U7VVjs.success.call(void 0, );
this.#lastContextValueTimestamp = timestamp;
this.#contextValue = value;
await Promise.all(
Array.from(this.#contextListeners.values()).map(async (listener) => {
const newSelectedValue = listener.selector(this.#contextValue);
const oldSelectedValue = listener.selector(oldContextValue);
const [errEqual, equal] = _chunkVLUR4YNDjs.canon.equal(newSelectedValue, oldSelectedValue);
if (errEqual) return _chunk22H3U7VVjs.failure.call(void 0, errEqual);
if (equal) return _chunk22H3U7VVjs.success.call(void 0, );
return await _chunk22H3U7VVjs.attempt.call(void 0,
async () => await listener.callback(_chunkBFC2WP6Qjs.deepClone.call(void 0, this.#contextValue), _chunkBFC2WP6Qjs.deepClone.call(void 0, oldContextValue))
);
})
);
return _chunk22H3U7VVjs.success.call(void 0, );
}
};
// transport/client/browser.ts
var clientTransportProviders = {
livekit: _chunkBFC2WP6Qjs.LiveKitBrowserClient
};
var TransportBrowserClient = class extends _chunkFID44QSNjs.TransportClientBase {
static {
_chunk6PEHRAEPjs.__name.call(void 0, this, "TransportBrowserClient");
}
constructor({
config,
obfuscateErrors = false,
telemetry = null
}) {
const ProviderClass = clientTransportProviders[config.provider];
super({ provider: new ProviderClass(config), obfuscateErrors, telemetry });
}
};
// agent/client/atoms/info.ts
var _nanostores = require('nanostores');
// agent/client/atoms/define.ts
function defineAgentAtom(atomDef) {
return atomDef;
}
_chunk6PEHRAEPjs.__name.call(void 0, defineAgentAtom, "defineAgentAtom");
// agent/client/atoms/info.ts
var atomConfigSchema = _zod2.default.object({
pollingMs: _zod2.default.number().min(1e3).max(3e4).prefault(5e3)
});
var agentInfoAtomDef = defineAgentAtom(({ agent }) => ({
name: "info",
create: /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (config) => {
const { error: errConfig, data: parsedConfig } = atomConfigSchema.safeParse(_nullishCoalesce(config, () => ( {})));
if (errConfig)
throw _chunk22H3U7VVjs.lifeError.call(void 0, { code: "Validation", message: "Invalid config provided to atom." });
const store = _nanostores.atom.call(void 0, null);
const refresh = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, async () => {
try {
const [error, data] = await agent.info();
if (error) throw error;
store.set(data);
} catch (error) {
throw _chunk22H3U7VVjs.lifeError.call(void 0, { code: "Unknown", cause: error });
}
}, "refresh");
_nanostores.onMount.call(void 0, store, () => {
refresh();
const intervalId = setInterval(() => refresh(), parsedConfig.pollingMs);
return () => clearInterval(intervalId);
});
return { store, refresh };
}, "create")
}));
// agent/client/atoms/index.ts
var createAgentClientAtoms = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (params) => ({
info: agentInfoAtomDef(params)
}), "createAgentClientAtoms");
// agent/client/class.ts
var AgentClient = (_class = class {
static {
_chunk6PEHRAEPjs.__name.call(void 0, this, "AgentClient");
}
#life;
#telemetry;
#plugins = {};
#sessionToken;
#transportRoom;
#scope;
__init() {this.isStarted = false}
constructor(params) {;_class.prototype.__init.call(this);
this.def = params.definition;
this.id = params.id;
this.name = params.definition.name;
this.config = params.config;
this.#life = params.life;
this.#telemetry = _chunkEL6AAGQAjs.createTelemetryClient.call(void 0, "agent.client", {
agentId: this.id,
agentName: this.name,
agentConfig: this.config,
transportProviderName: this.config.transport.provider
});
this.transport = new TransportBrowserClient({
config: this.config.transport,
telemetry: this.#telemetry
});
this.atoms = createAgentClientAtoms({ agent: this, telemetry: this.#telemetry });
const [errInitialize] = this.#initializePlugins(this.def.plugins);
if (errInitialize) throw errInitialize;
}
#initializePlugins(plugins) {
return this.#telemetry.trace("#initializePlugins()", () => {
try {
const pluginNames = plugins.map((plugin) => plugin.name);
const duplicates = pluginNames.filter((name2, index) => pluginNames.indexOf(name2) !== index);
if (duplicates.length > 0) {
const uniqueDuplicates = [...new Set(duplicates)];
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Validation",
message: `Two or more plugins are named '${uniqueDuplicates.join("', '")}'. Plugin names must be unique. (agent: '${this.name}')`
});
}
for (const plugin of plugins) {
for (const dependency of plugin.dependencies) {
const depPlugin = this.def.plugins.find((p) => p.name === dependency.name);
if (!depPlugin) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Validation",
message: `Plugin '${plugin.name}' depends on plugin '${dependency.name}', but '${dependency.name}' is not registered. (agent: '${this.name}')`
});
}
}
}
const initResults = plugins.map((plugin) => {
const [errPlugin, pluginInstance] = _chunk22H3U7VVjs.attempt.call(void 0,
() => new PluginClient(
plugin,
_nullishCoalesce(this.def.pluginConfigs[plugin.name], () => ( {})),
this
)
);
if (errPlugin) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: `Failed to initialize plugin '${name}'.`,
cause: errPlugin
});
}
this.#plugins[plugin.name] = pluginInstance;
const [errAccessor, accessor] = pluginInstance.getAccessor();
if (errAccessor) return _chunk22H3U7VVjs.failure.call(void 0, errAccessor);
this[_chunkOTBM3PZSjs.toMethodName.call(void 0, plugin.name)] = accessor;
return _chunk22H3U7VVjs.success.call(void 0, );
});
for (const result of initResults) {
const [error] = result;
if (error) this.#telemetry.log.error({ error });
}
return _chunk22H3U7VVjs.success.call(void 0, );
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while initializing plugins.",
cause: error
});
}
});
}
/**
* Start the agent and join the transport room
* @returns Server response on successful start
* @throws Error if the agent fails to start
*/
async start(scope) {
return await this.#telemetry.trace("start()", async (span) => {
const [error] = await this.#start(scope);
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, );
});
}
// Private method, doesn't log to telemetry
async #start(scope) {
return await this.#telemetry.trace("#start()", async () => {
try {
const [errStart, data] = await this.#life.api.call("agent.start", { id: this.id, scope });
if (errStart) return _chunk22H3U7VVjs.failure.call(void 0, errStart);
this.#sessionToken = data.sessionToken;
this.#transportRoom = data.transportRoom;
this.#scope = scope;
const [errJoin] = await this.transport.joinRoom(
this.#transportRoom.name,
this.#transportRoom.token
);
if (errJoin) return _chunk22H3U7VVjs.failure.call(void 0, errJoin);
const results = await Promise.all(Object.values(this.#plugins).map((p) => p.start()));
const errors = results.map((r) => r[0]).filter(Boolean);
for (const error of errors)
this.#telemetry.log.error({ message: "Failed to start plugin.", error });
this.isStarted = true;
return _chunk22H3U7VVjs.success.call(void 0, );
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while starting agent.",
cause: error
});
}
});
}
/**
* Stop the agent and leave the transport room
* @returns Server response on successful stop
* @throws Error if the agent fails to stop
*/
async stop() {
return await this.#telemetry.trace("stop()", async (span) => {
const [error] = await this.#stop();
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, );
});
}
// Private method, doesn't log to telemetry
async #stop() {
return await this.#telemetry.trace("#stop()", async () => {
try {
if (!this.#sessionToken) {
return _chunk22H3U7VVjs.failure.call(void 0, { code: "Conflict", message: "Agent is not started." });
}
const [apiResult, roomResult] = await Promise.all([
this.#life.api.call("agent.stop", {
id: this.id,
sessionToken: this.#sessionToken
}),
this.transport.leaveRoom()
]);
if (apiResult[0]) return _chunk22H3U7VVjs.failure.call(void 0, apiResult[0]);
if (roomResult[0]) return _chunk22H3U7VVjs.failure.call(void 0, roomResult[0]);
this.isStarted = false;
return _chunk22H3U7VVjs.success.call(void 0, );
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while stopping agent.",
cause: error
});
}
});
}
/**
* Restart the agent by stopping and starting it
*/
async restart() {
return await this.#telemetry.trace("restart()", async (span) => {
const [error] = await this.#restart();
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, );
});
}
// Private method, doesn't log to telemetry
async #restart() {
return await this.#telemetry.trace("#restart()", async () => {
try {
const [errStop] = await this.#stop();
if (errStop) return _chunk22H3U7VVjs.failure.call(void 0, errStop);
if (!this.#scope) {
return _chunk22H3U7VVjs.failure.call(void 0, { code: "Conflict", message: "Agent is not started." });
}
const [errStart] = await this.#start(this.#scope);
if (errStart) return _chunk22H3U7VVjs.failure.call(void 0, errStart);
return _chunk22H3U7VVjs.success.call(void 0, );
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while restarting agent.",
cause: error
});
}
});
}
async enableVoiceIn() {
const [errEnableMicrophone] = await this.transport.enableMicrophone();
if (errEnableMicrophone) return _chunk22H3U7VVjs.failure.call(void 0, errEnableMicrophone);
return _chunk22H3U7VVjs.success.call(void 0, );
}
async enableVoiceOut() {
const [errPlayAudio] = await this.transport.playAudio();
if (errPlayAudio) return _chunk22H3U7VVjs.failure.call(void 0, errPlayAudio);
return _chunk22H3U7VVjs.success.call(void 0, );
}
async disableVoiceIn() {
return await _chunk22H3U7VVjs.success.call(void 0, );
}
async disableVoiceOut() {
return await _chunk22H3U7VVjs.success.call(void 0, );
}
/**
* Get agent information from the server
* @returns Agent information including status and metrics
* @throws Error if unable to retrieve agent info
*/
async info() {
return await this.#telemetry.trace("info()", async (span) => {
const [error, data] = await this.#info();
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, data);
});
}
// Private method, doesn't log to telemetry
async #info() {
return await this.#telemetry.trace("#info()", async () => {
try {
if (!this.#sessionToken) {
return _chunk22H3U7VVjs.failure.call(void 0, { code: "Conflict", message: "Agent is not started." });
}
const [err, data] = await this.#life.api.call("agent.info", {
id: this.id,
sessionToken: this.#sessionToken
});
if (err) return _chunk22H3U7VVjs.failure.call(void 0, err);
return _chunk22H3U7VVjs.success.call(void 0, data);
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while getting agent info.",
cause: error
});
}
});
}
}, _class);
// telemetry/helpers/formatting/browser.ts
var _tracemapping = require('@jridgewell/trace-mapping');
var _errorstackparser = require('error-stack-parser'); var _errorstackparser2 = _interopRequireDefault(_errorstackparser);
var sourceMapCache = /* @__PURE__ */ new Map();
async function getSourceMap(file) {
if (sourceMapCache.has(file)) return _nullishCoalesce(sourceMapCache.get(file), () => ( null));
try {
const mapUrl = `${file}.map`;
const r = await fetch(mapUrl, { credentials: "same-origin" });
if (!r.ok) return _nullishCoalesce(sourceMapCache.set(file, null).get(file), () => ( null));
const json = await r.json();
let map;
try {
map = new (0, _tracemapping.TraceMap)(json);
} catch (error) {
if (error instanceof Error && error.message.includes("sectioned source map")) {
map = new (0, _tracemapping.FlattenMap)(json);
} else {
throw error;
}
}
return _nullishCoalesce(sourceMapCache.set(file, map).get(file), () => ( null));
} catch (error) {
console.error("Failed to get source map for", file, error);
return _nullishCoalesce(sourceMapCache.set(file, null).get(file), () => ( null));
}
}
_chunk6PEHRAEPjs.__name.call(void 0, getSourceMap, "getSourceMap");
async function prettifyErrorStack(err_) {
const err = _chunkBFC2WP6Qjs.deepClone.call(void 0, err_);
const frames = safeParse(err);
const lines = [];
for (const f of frames) {
const file = _optionalChain([f, 'access', _12 => _12.fileName, 'optionalAccess', _13 => _13.startsWith, 'call', _14 => _14("async ")]) ? f.fileName.slice(6) : f.fileName;
const line = f.lineNumber;
const col = f.columnNumber;
let ref = "<unknown>";
if (file && line != null && col != null) {
const map = await getSourceMap(file);
if (map) {
const pos = _tracemapping.originalPositionFor.call(void 0, map, { line, column: col, bias: 1 });
if (pos.source && pos.line != null && pos.column != null) {
ref = `${pos.source}:${pos.line}:${pos.column}`;
}
}
if (!ref) ref = `${file}:${line}:${col}`;
}
lines.push(f.functionName ? ` at ${f.functionName} (${ref})` : ` at ${ref}`);
}
err.stack = lines.join("\n");
return err;
}
_chunk6PEHRAEPjs.__name.call(void 0, prettifyErrorStack, "prettifyErrorStack");
function safeParse(err) {
try {
return _errorstackparser2.default.parse(err);
} catch (e) {
return [
{
fileName: void 0,
lineNumber: void 0,
columnNumber: void 0,
functionName: err.name || "Error"
}
];
}
}
_chunk6PEHRAEPjs.__name.call(void 0, safeParse, "safeParse");
async function formatErrorForBrowser(error) {
let code = "";
let message = "";
let stack = "";
const after = [];
let processed = false;
if (_chunk22H3U7VVjs.isLifeError.call(void 0, error)) {
code = `LifeError (${error.code})`;
message = error.message;
stack = await _asyncNullishCoalesce((await prettifyErrorStack(error)).stack, async () => ( ""));
if (error.cause) {
const formatted = await formatErrorForBrowser(error.cause);
after.push(formatted.content, ...formatted.after);
const typedCause = error.cause;
if (error.code === "Unknown" && _optionalChain([typedCause, 'optionalAccess', _15 => _15.stack])) stack = "";
}
processed = true;
} else if (error instanceof _zod2.default.ZodError) {
code = "ZodError";
message = _zod2.default.prettifyError(error);
stack = await _asyncNullishCoalesce((await prettifyErrorStack(error)).stack, async () => ( ""));
processed = true;
}
if (!processed && error instanceof Error) {
if ("name" in error && typeof error.name === "string") code = error.name;
else if ("code" in error && typeof error.code === "string") code = error.code;
if ("message" in error && typeof error.message === "string") message = error.message;
else if ("reason" in error && typeof error.reason === "string") message = error.reason;
if ("stack" in error && typeof error.stack === "string") {
stack = await _asyncNullishCoalesce((await prettifyErrorStack(error)).stack, async () => ( ""));
}
stack = _nullishCoalesce(_optionalChain([stack, 'optionalAccess', _16 => _16.split, 'call', _17 => _17("\n"), 'optionalAccess', _18 => _18.filter, 'call', _19 => _19((line) => !line.includes(error.message.trim())), 'optionalAccess', _20 => _20.join, 'call', _21 => _21("\n")]), () => ( ""));
if (!code) code = "Unknown Error";
if (!message) message = "An unknown error occurred.";
if (!stack) stack = "";
}
if (error instanceof Error && error.cause) {
const formatted = await formatErrorForBrowser(error.cause);
after.push(formatted.content, ...formatted.after);
}
return {
content: `${code}${code ? ": " : ""}${message}${message ? " " : ""}${stack ? `
${stack}` : ""}`,
after
};
}
_chunk6PEHRAEPjs.__name.call(void 0, formatErrorForBrowser, "formatErrorForBrowser");
async function formatLogForBrowser(log) {
let prefix;
if (log.level === "fatal") prefix = "\u2718";
else if (log.level === "error") prefix = "\u2718";
else if (log.level === "warn") prefix = "\u25B2";
else if (log.level === "info") prefix = "\u29BF";
else prefix = "\u2234";
const scopeDefinition = _optionalChain([_chunkEL6AAGQAjs.telemetryBrowserScopesDefinition, 'optionalAccess', _22 => _22[log.scope]]);
const scopeDisplayName = _optionalChain([scopeDefinition, 'optionalAccess', _23 => _23.displayName]) instanceof Function ? (
// biome-ignore lint/suspicious/noExplicitAny: fine here
scopeDefinition.displayName(log.attributes)
) : _optionalChain([scopeDefinition, 'optionalAccess', _24 => _24.displayName]);
const scope = `[${_nullishCoalesce(scopeDisplayName, () => ( "Unknown"))}]`;
const message = log.message || "";
const header = `${prefix} ${scope}${message ? ` ${message}` : ""}`;
const formatted = await formatErrorForBrowser(log.error);
const errors = [formatted.content, ...formatted.after];
return [header, ...errors];
}
_chunk6PEHRAEPjs.__name.call(void 0, formatLogForBrowser, "formatLogForBrowser");
// client/api.ts
var WS_PROTOCOL_REGEX = /^http/;
var TRAILING_SLASH_REGEX = /\/$/;
var SUBSCRIPTION_ID_LENGTH = 16;
var LifeServerApiClient = class {
static {
_chunk6PEHRAEPjs.__name.call(void 0, this, "LifeServerApiClient");
}
#telemetry;
#serverUrl;
#serverToken;
#ws;
#subscriptions = /* @__PURE__ */ new Map();
#wsReconnectTimeout;
constructor(params) {
this.#telemetry = params.telemetry;
this.#serverUrl = params.serverUrl.replace(TRAILING_SLASH_REGEX, "");
this.#serverToken = params.serverToken;
}
ensureWebSocket() {
if (_optionalChain([this, 'access', _25 => _25.#ws, 'optionalAccess', _26 => _26.readyState]) === WebSocket.OPEN) return Promise.resolve(this.#ws);
return new Promise((resolve, reject) => {
const wsUrl = `${this.#serverUrl.replace(WS_PROTOCOL_REGEX, "ws")}/api/ws`;
this.#ws = new WebSocket(wsUrl);
this.#ws.onopen = () => {
if (this.#ws) resolve(this.#ws);
};
this.#ws.onerror = () => {
reject(_chunk22H3U7VVjs.lifeError.call(void 0, { code: "Upstream", message: "WebSocket connection failed" }));
};
this.#ws.onmessage = (event) => {
try {
const [err, message] = _chunkVLUR4YNDjs.canon.parse(event.data);
if (err) return;
if (!message || typeof message !== "object" || message === null) return;
if (!("subscriptionId" in message) || typeof message.subscriptionId !== "string") return;
const callback = this.#subscriptions.get(message.subscriptionId);
_optionalChain([callback, 'optionalCall', _27 => _27(message.data)]);
} catch (e2) {
}
};
this.#ws.onclose = () => {
if (this.#subscriptions.size > 0) {
this.#wsReconnectTimeout = setTimeout(() => {
this.ensureWebSocket().catch(() => {
});
}, 5e3);
}
};
});
}
async call(handlerId, input) {
return await this.#telemetry.trace("api.call()", async () => {
const url = `${this.#serverUrl}/api/http`;
const headers = { "Content-Type": "application/json" };
if (this.#serverToken) headers.Authorization = `Bearer ${this.#serverToken}`;
try {
const [errCanon, body] = _chunkVLUR4YNDjs.canon.stringify({
handlerId,
serverToken: this.#serverToken,
data: input
});
if (errCanon) return _chunk22H3U7VVjs.failure.call(void 0, errCanon);
const response = await fetch(url, {
method: "POST",
headers,
body
});
if (!response.ok) {
try {
const result = _chunkVLUR4YNDjs.canon.parse(await response.text());
return _chunk22H3U7VVjs.failure.call(void 0,
_nullishCoalesce(_optionalChain([result, 'optionalAccess', _28 => _28[0]]), () => ( {
code: "Upstream",
message: `API call failed: ${response.statusText}`
}))
);
} catch (e3) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Upstream",
message: `API call failed: ${response.statusText}`
});
}
}
const text = await response.text();
const [err, data] = _chunkVLUR4YNDjs.canon.parse(text);
if (err) return _chunk22H3U7VVjs.failure.call(void 0, err);
return _chunk22H3U7VVjs.success.call(void 0, data);
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, { code: "Unknown", cause: error });
}
});
}
cast(handlerId, input) {
return this.#telemetry.trace("api.cast()", async () => {
const ws = await this.ensureWebSocket();
const [errCanon, body] = _chunkVLUR4YNDjs.canon.stringify({
type: "cast",
handlerId,
serverToken: this.#serverToken,
data: input
});
if (errCanon) return _chunk22H3U7VVjs.failure.call(void 0, errCanon);
return await _chunk22H3U7VVjs.attempt.call(void 0, async () => ws.send(body));
});
}
subscribe(handlerId, callback, input) {
return this.#telemetry.trace("api.subscribe()", () => {
try {
const subscriptionId = `sub_${Date.now()}_${Math.random().toString(36).substring(2, 2 + SUBSCRIPTION_ID_LENGTH)}`;
this.#subscriptions.set(subscriptionId, callback);
this.ensureWebSocket().then((ws) => {
const [errCanon, body] = _chunkVLUR4YNDjs.canon.stringify({
type: "stream",
action: "subscribe",
handlerId,
subscriptionId,
serverToken: this.#serverToken,
data: input
});
if (errCanon) return _chunk22H3U7VVjs.failure.call(void 0, errCanon);
ws.send(body);
}).catch(() => {
this.#subscriptions.delete(subscriptionId);
});
const unsubscribe = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, () => {
this.#subscriptions.delete(subscriptionId);
if (_optionalChain([this, 'access', _29 => _29.#ws, 'optionalAccess', _30 => _30.readyState]) === WebSocket.OPEN) {
const [errCanon, body] = _chunkVLUR4YNDjs.canon.stringify({
type: "stream",
action: "unsubscribe",
handlerId,
subscriptionId,
serverToken: this.#serverToken
});
if (errCanon) return _chunk22H3U7VVjs.failure.call(void 0, errCanon);
this.#ws.send(body);
}
}, "unsubscribe");
return _chunk22H3U7VVjs.success.call(void 0, unsubscribe);
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, { code: "Unknown", cause: error });
}
});
}
disconnect() {
if (this.#wsReconnectTimeout) {
clearTimeout(this.#wsReconnectTimeout);
this.#wsReconnectTimeout = void 0;
}
this.#subscriptions.clear();
if (this.#ws) {
this.#ws.close();
this.#ws = void 0;
}
}
};
// client/client.ts
_chunkEL6AAGQAjs.TelemetryBrowserClient.registerGlobalConsumer({
async start(queue) {
for await (const item of queue) {
if (item.type !== "log") continue;
const logLevel = _nullishCoalesce(_optionalChain([globalThis, 'optionalAccess', _31 => _31.process, 'optionalAccess', _32 => _32.env, 'optionalAccess', _33 => _33.LOG_LEVEL]), () => ( "info"));
const priority = _chunkEL6AAGQAjs.logLevelPriority.call(void 0, item.level);
if (priority < _chunkEL6AAGQAjs.logLevelPriority.call(void 0, logLevel)) continue;
try {
const contents = (await formatLogForBrowser(item)).filter(Boolean);
let consoleFn;
if (priority >= _chunkEL6AAGQAjs.logLevelPriority.call(void 0, "error")) consoleFn = console.error;
else if (priority >= _chunkEL6AAGQAjs.logLevelPriority.call(void 0, "warn")) consoleFn = console.warn;
else consoleFn = console.log;
for (let i = 0; i < contents.length; i++)
consoleFn(
`Life.js (${item.id.slice(0, 6)}, ${i + 1}/${contents.length})
${contents[i]}`
);
} catch (e4) {
console.log(item.message);
}
}
}
});
var LifeClient = class {
static {
_chunk6PEHRAEPjs.__name.call(void 0, this, "LifeClient");
}
#agents = /* @__PURE__ */ new Map();
#telemetry;
constructor(options) {
this.options = options;
this.#telemetry = _chunkEL6AAGQAjs.createTelemetryClient.call(void 0, "client", {});
this.api = new LifeServerApiClient({
telemetry: this.#telemetry,
serverUrl: this.options.serverUrl,
serverToken: this.options.serverToken
});
}
/**
* Create a new agent instance on the server
* @param name - Agent name/type to create
* @param scope - Agent scope configuration
* @returns AgentClient instance if creation successful
*/
async createAgent(name2, options = {}) {
return await this.#telemetry.trace("createAgent()", async (span) => {
const [error, agent] = await this.#createAgent(name2, options);
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, agent);
});
}
// Private method, doesn't log to telemetry
async #createAgent(name2, options = {}) {
return await this.#telemetry.trace("#createAgent()", async () => {
try {
const [errIndex, buildIndex] = await _chunkW2LGDDT2js.importClientBuild.call(void 0, );
if (errIndex) return _chunk22H3U7VVjs.failure.call(void 0, errIndex);
const build = buildIndex[name2];
if (!build) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "NotFound",
message: `Agent '${String(name2)}' not found in client build.`
});
}
const [err, data] = await this.api.call("agent.create", { name: name2, id: options.id });
if (err) return _chunk22H3U7VVjs.failure.call(void 0, err);
const agentClient = new AgentClient({
id: data.id,
definition: build.definition,
life: this,
config: _nullishCoalesce(data.clientConfig, () => ( {}))
});
this.#agents.set(data.id, agentClient);
return _chunk22H3U7VVjs.success.call(void 0, _chunk22H3U7VVjs.toPublic.call(void 0, agentClient));
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while creating agent.",
cause: error
});
}
});
}
/**
* Get an existing agent client instance
* @param id - Agent ID
* @returns AgentClient instance or undefined
*/
getAgent(name2, options = {}) {
return this.#telemetry.trace("getAgent()", (span) => {
const [error, agent] = this.#getAgent(name2, options);
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, agent);
});
}
// Private method, doesn't log to telemetry
#getAgent(name2, options = {}) {
return this.#telemetry.trace("#getAgent()", () => {
try {
if (options.id) {
const agent = this.#agents.get(options.id);
if (!agent) return _chunk22H3U7VVjs.success.call(void 0, void 0);
return _chunk22H3U7VVjs.success.call(void 0, _chunk22H3U7VVjs.toPublic.call(void 0, agent));
}
const agents = Array.from(this.#agents.values()).filter((a) => a.def.name === String(name2));
if (!agents.length) return _chunk22H3U7VVjs.success.call(void 0, void 0);
if (agents.length > 1)
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Conflict",
message: `Multiple agents found for name '${String(name2)}'. Use an ID to get a specific agent.`
});
return _chunk22H3U7VVjs.success.call(void 0, _chunk22H3U7VVjs.toPublic.call(void 0, agents[0]));
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while getting agent.",
cause: error
});
}
});
}
/**
* Get or create an agent instance
* @param name - Agent name/type
* @param scope - Agent scope configuration
* @returns AgentClient instance
*/
async getOrCreateAgent(name2, options = {}) {
return await this.#telemetry.trace("getOrCreateAgent()", async (span) => {
const [error, agent] = await this.#getOrCreateAgent(name2, options);
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, agent);
});
}
// Private method, doesn't log to telemetry
async #getOrCreateAgent(name2, options = {}) {
return await this.#telemetry.trace("#getOrCreateAgent()", async () => {
try {
const [error, agent] = this.getAgent(name2, options);
if (error && error.code !== "Conflict") return _chunk22H3U7VVjs.failure.call(void 0, error);
if (agent) return _chunk22H3U7VVjs.success.call(void 0, agent);
const [err, newAgent] = await this.#createAgent(name2, options);
if (err) return _chunk22H3U7VVjs.failure.call(void 0, err);
return _chunk22H3U7VVjs.success.call(void 0, newAgent);
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while getting or creating agent.",
cause: error
});
}
});
}
/**
* List all created agent instances
* @returns Array of { name: string, id: string }
*/
listAgents() {
return this.#telemetry.trace("listAgents()", (span) => {
const [error, agents] = this.#listAgents();
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, agents);
});
}
// Private method, doesn't log to telemetry
#listAgents() {
return this.#telemetry.trace("#listAgents()", () => {
try {
return _chunk22H3U7VVjs.success.call(void 0,
Array.from(this.#agents.values()).map((a) => ({ name: a.name, id: a.id }))
);
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while listing agents.",
cause: error
});
}
});
}
/**
* Get server information
* @returns Server info response
*/
async info() {
return await this.#telemetry.trace("info()", async (span) => {
const [error, data] = await this.#info();
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, data);
});
}
// Private method, doesn't log to telemetry
async #info() {
return await this.#telemetry.trace("info()", async () => {
try {
const [err, data] = await this.api.call("server.info");
if (err) return _chunk22H3U7VVjs.failure.call(void 0, err);
return _chunk22H3U7VVjs.success.call(void 0, data);
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while getting server info.",
cause: error
});
}
});
}
/**
* Check if the server is responsive
* @returns True if server responds with "pong"
*/
async ping() {
return await this.#telemetry.trace("ping()", async (span) => {
const [error, data] = await this.#ping();
if (error) {
span.log.error({ error });
return _chunk22H3U7VVjs.failure.call(void 0, error);
}
return _chunk22H3U7VVjs.success.call(void 0, data);
});
}
// Private method, doesn't log to telemetry
async #ping() {
return await this.#telemetry.trace("#ping()", async () => {
try {
const [err, data] = await this.api.call("server.ping");
if (err) return _chunk22H3U7VVjs.failure.call(void 0, err);
if (data !== "pong")
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Validation",
message: `Ping failed. Received wrong response: '${data}'.`
});
return _chunk22H3U7VVjs.success.call(void 0, "pong");
} catch (error) {
return _chunk22H3U7VVjs.failure.call(void 0, {
code: "Unknown",
message: "Unknown error while pinging server.",
cause: error
});
}
});
}
};
// client/options.ts
var lifeClientOptionsSchema = _zod2.default.object({
serverUrl: _zod2.default.string().prefault("http://localhost:3003"),
serverToken: _zod2.default.string().optional()
});
// client/create.ts
var getClientCache = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, () => {
if (!globalThis.__LIFE_CLIENT_CACHE__) globalThis.__LIFE_CLIENT_CACHE__ = /* @__PURE__ */ new Map();
return globalThis.__LIFE_CLIENT_CACHE__;
}, "getClientCache");
var getCacheKey = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (options) => `${options.serverUrl}::${_nullishCoalesce(options.serverToken, () => ( ""))}`, "getCacheKey");
var createLifeClient = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (options = {}) => {
const { error: errOptions, data: parsedOptions } = lifeClientOptionsSchema.safeParse(options);
if (errOptions) {
throw _chunk22H3U7VVjs.lifeError.call(void 0, {
code: "Validation",
message: "Invalid options provided to LifeClient.",
cause: errOptions
});
}
if (typeof window === "undefined") return { options: parsedOptions };
const cache = getClientCache();
const key = getCacheKey(parsedOptions);
const client = cache.get(key);
if (client) return client;
const newClient = _chunk22H3U7VVjs.toPublic.call(void 0, new LifeClient(parsedOptions));
cache.set(key, newClient);
return newClient;
}, "createLifeClient");
_optionalChain([hmr, 'access', _34 => _34.accept, 'optionalCall', _35 => _35()]);
// agent/client/types.ts
var parseAgentClientParam = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (agent) => agent, "parseAgentClientParam");
exports.createLifeClient = createLifeClient; exports.parseAgentClientParam = parseAgentClientParam;
//# sourceMappingURL=chunk-SDCJCCXN.js.map