@letta-ai/letta-agent-sdk 0.8.34 → 0.8.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -17791,20 +17791,21 @@ function buildLocalAppServerProcess(cliPath, options = {}, confineMemory = creat
17791
17791
  process.execPath,
17792
17792
  ...buildLocalAppServerArgs(cliPath, options)
17793
17793
  ];
17794
- if (options.filesystemConfinement !== "memory") {
17795
- return {
17796
- command: launcher[0],
17797
- args: launcher.slice(1),
17798
- env
17799
- };
17800
- }
17801
- const confined = confineMemory({
17802
- launcher,
17803
- env: withDefaultMemoryDirectory(env, options)
17804
- });
17794
+ const confined = options.filesystemConfinement === "memory" ? confineMemory({ launcher, env: withDefaultMemoryDirectory(env, options) }) : { launcher, env };
17795
+ const slice = env.LETTA_WORKLOAD_SYSTEMD_SLICE?.trim();
17796
+ const managedLauncher = process.platform === "linux" && slice ? [
17797
+ "systemd-run",
17798
+ "--scope",
17799
+ "--quiet",
17800
+ "--collect",
17801
+ "--property=TimeoutStopSec=5s",
17802
+ `--slice=${slice}`,
17803
+ "--",
17804
+ ...confined.launcher
17805
+ ] : confined.launcher;
17805
17806
  return {
17806
- command: confined.launcher[0],
17807
- args: confined.launcher.slice(1),
17807
+ command: managedLauncher[0],
17808
+ args: managedLauncher.slice(1),
17808
17809
  env: confined.env
17809
17810
  };
17810
17811
  }
@@ -17851,6 +17852,7 @@ function startLocalAppServer(options = {}) {
17851
17852
  cleanup();
17852
17853
  resolve3({
17853
17854
  url,
17855
+ isRunning: () => child.exitCode === null && child.signalCode === null,
17854
17856
  close: () => terminateProcess(child)
17855
17857
  });
17856
17858
  };
@@ -17883,12 +17885,14 @@ ${output.trim()}` : ""}`));
17883
17885
  }
17884
17886
 
17885
17887
  // src/local-app-server-session.ts
17886
- function createLocalAppServerSession(options, mode) {
17888
+ function createLocalAppServerSession(options, mode, sharedServer) {
17887
17889
  const appServer = options ?? {};
17890
+ const session = mode.options;
17891
+ const needsOwnProcess = session.filesystemConfinement === "memory" || Object.keys(session.env ?? {}).length > 0;
17888
17892
  const sessionOptions = {
17889
17893
  ...mode.kind === "conversation" && (appServer.harnessBackend ?? "local") === "local" ? { requireLocalConversationCapability: true } : {},
17890
17894
  ...appServer.url !== undefined ? { url: appServer.url } : {
17891
- connect: (sessionEnv) => startLocalAppServer({
17895
+ connect: (sessionEnv) => sharedServer && !needsOwnProcess ? sharedServer.connect() : startLocalAppServer({
17892
17896
  listen: appServer.listen,
17893
17897
  backend: appServer.harnessBackend ?? "local",
17894
17898
  startupTimeoutMs: appServer.startupTimeoutMs,
@@ -17904,6 +17908,54 @@ function createLocalAppServerSession(options, mode) {
17904
17908
  return new AppServerSession(sessionOptions, mode);
17905
17909
  }
17906
17910
 
17911
+ // src/shared-local-app-server.ts
17912
+ class SharedLocalAppServer {
17913
+ options;
17914
+ starting = null;
17915
+ server = null;
17916
+ closed = false;
17917
+ closing = null;
17918
+ constructor(options) {
17919
+ this.options = options;
17920
+ }
17921
+ async connect() {
17922
+ if (this.closed)
17923
+ throw new Error("Local App Server owner is closed");
17924
+ if (this.server && !this.server.isRunning()) {
17925
+ this.server = null;
17926
+ this.starting = null;
17927
+ }
17928
+ if (!this.starting) {
17929
+ this.starting = startLocalAppServer(this.options).then((server2) => {
17930
+ if (this.closed) {
17931
+ server2.close();
17932
+ throw new Error("Local App Server owner closed during startup");
17933
+ }
17934
+ this.server = server2;
17935
+ return server2;
17936
+ }, (error) => {
17937
+ this.starting = null;
17938
+ throw error;
17939
+ });
17940
+ }
17941
+ const server = await this.starting;
17942
+ if (this.closed)
17943
+ throw new Error("Local App Server owner is closed");
17944
+ return {
17945
+ url: server.url,
17946
+ isRunning: server.isRunning,
17947
+ close() {}
17948
+ };
17949
+ }
17950
+ close() {
17951
+ if (this.closing)
17952
+ return this.closing;
17953
+ this.closed = true;
17954
+ this.closing = this.starting ? this.starting.then((server) => server.close(), () => {}) : Promise.resolve();
17955
+ return this.closing;
17956
+ }
17957
+ }
17958
+
17907
17959
  // src/skill-node.ts
17908
17960
  import { readFile, readdir, stat, mkdtemp, rm, mkdir, writeFile } from "node:fs/promises";
17909
17961
  import { tmpdir } from "node:os";
@@ -17992,18 +18044,36 @@ async function pushSkillSupportFiles(target, skills) {
17992
18044
 
17993
18045
  // src/client.ts
17994
18046
  class LettaAgentClient extends LettaAgentClientBase {
18047
+ localServer = null;
18048
+ localClosePromise = null;
18049
+ sharedLocalServer() {
18050
+ if (this.localClosePromise)
18051
+ throw new Error("LettaAgentClient is closed");
18052
+ const options = this.options.appServer;
18053
+ return this.localServer ??= new SharedLocalAppServer({
18054
+ listen: options?.listen,
18055
+ backend: options?.harnessBackend ?? "local",
18056
+ startupTimeoutMs: options?.startupTimeoutMs
18057
+ });
18058
+ }
18059
+ close() {
18060
+ if (!this.localClosePromise) {
18061
+ this.localClosePromise = Promise.all([
18062
+ super.close(),
18063
+ this.localServer?.close()
18064
+ ]).then(() => {});
18065
+ }
18066
+ return this.localClosePromise;
18067
+ }
17995
18068
  skillNodeSupport() {
17996
18069
  return { loadSkillDirectory, pushSkillSupportFiles };
17997
18070
  }
17998
18071
  createLocalManagementTransport() {
17999
18072
  const localOptions = this.options.appServer;
18073
+ const sharedServer = this.sharedLocalServer();
18000
18074
  return new AppServerManagementTransport({
18001
18075
  ...localOptions?.url !== undefined ? { url: localOptions.url } : {
18002
- connect: () => startLocalAppServer({
18003
- listen: localOptions?.listen,
18004
- backend: localOptions?.harnessBackend ?? "local",
18005
- startupTimeoutMs: localOptions?.startupTimeoutMs
18006
- })
18076
+ connect: () => sharedServer.connect()
18007
18077
  },
18008
18078
  ...localOptions?.WebSocket !== undefined ? { WebSocket: localOptions.WebSocket } : {},
18009
18079
  ...localOptions?.requestTimeoutMs !== undefined ? { requestTimeoutMs: localOptions.requestTimeoutMs } : {}
@@ -18014,13 +18084,16 @@ class LettaAgentClient extends LettaAgentClientBase {
18014
18084
  const session = createLocalAppServerSession(localOptions.appServer, {
18015
18085
  kind: "create-agent",
18016
18086
  options
18017
- });
18018
- const initMsg = await session.initialize();
18019
- session.close();
18020
- if (!initMsg.agentId) {
18021
- throw new Error("Local App Server agent creation did not return an agent id.");
18087
+ }, this.sharedLocalServer());
18088
+ try {
18089
+ const initMsg = await session.initialize();
18090
+ if (!initMsg.agentId) {
18091
+ throw new Error("Local App Server agent creation did not return an agent id.");
18092
+ }
18093
+ return initMsg.agentId;
18094
+ } finally {
18095
+ session.close();
18022
18096
  }
18023
- return initMsg.agentId;
18024
18097
  }
18025
18098
  createLocalSession(agentId, options) {
18026
18099
  const localOptions = this.options;
@@ -18029,7 +18102,7 @@ class LettaAgentClient extends LettaAgentClientBase {
18029
18102
  agentId,
18030
18103
  newConversation: true,
18031
18104
  options
18032
- });
18105
+ }, this.sharedLocalServer());
18033
18106
  }
18034
18107
  createLocalQuerySession(queryOptions, sessionOptions) {
18035
18108
  const localOptions = this.options;
@@ -18048,7 +18121,7 @@ class LettaAgentClient extends LettaAgentClientBase {
18048
18121
  },
18049
18122
  options: sessionOptions,
18050
18123
  ...queryOptions.disableMemoryGuard === true ? { disableMemoryGuard: true } : {}
18051
- });
18124
+ }, this.sharedLocalServer());
18052
18125
  }
18053
18126
  resumeLocalSession(id, options) {
18054
18127
  const localOptions = this.options;
@@ -18057,14 +18130,14 @@ class LettaAgentClient extends LettaAgentClientBase {
18057
18130
  kind: "session",
18058
18131
  conversationId: id,
18059
18132
  options
18060
- });
18133
+ }, this.sharedLocalServer());
18061
18134
  }
18062
18135
  return createLocalAppServerSession(localOptions.appServer, {
18063
18136
  kind: "session",
18064
18137
  agentId: id,
18065
18138
  defaultConversation: true,
18066
18139
  options
18067
- });
18140
+ }, this.sharedLocalServer());
18068
18141
  }
18069
18142
  }
18070
18143
  function looksLikeConversationId2(id) {
@@ -35589,15 +35662,41 @@ import { readFileSync } from "node:fs";
35589
35662
  registerMcpConnector(connectMcpServers2);
35590
35663
  async function createAgent(options = {}) {
35591
35664
  validateCreateAgentOptions(options);
35592
- return new LettaAgentClient().createAgent(options);
35665
+ const client = new LettaAgentClient;
35666
+ try {
35667
+ return await client.createAgent(options);
35668
+ } finally {
35669
+ await client.close();
35670
+ }
35671
+ }
35672
+ function ownSession(client, session) {
35673
+ const close = session.close.bind(session);
35674
+ const dispose = session[Symbol.asyncDispose].bind(session);
35675
+ session.close = () => {
35676
+ try {
35677
+ close();
35678
+ } finally {
35679
+ client.close();
35680
+ }
35681
+ };
35682
+ session[Symbol.asyncDispose] = async () => {
35683
+ try {
35684
+ await dispose();
35685
+ } finally {
35686
+ await client.close();
35687
+ }
35688
+ };
35689
+ return session;
35593
35690
  }
35594
35691
  function createSession(agentId, options = {}) {
35595
35692
  validateCreateSessionOptions(options);
35596
- return new LettaAgentClient().createSession(agentId, options);
35693
+ const client = new LettaAgentClient;
35694
+ return ownSession(client, client.createSession(agentId, options));
35597
35695
  }
35598
35696
  function resumeSession(id, options = {}) {
35599
35697
  validateCreateSessionOptions(options);
35600
- return new LettaAgentClient().resumeSession(id, options);
35698
+ const client = new LettaAgentClient;
35699
+ return ownSession(client, client.resumeSession(id, options));
35601
35700
  }
35602
35701
  async function prompt(message, agentId, options = {}) {
35603
35702
  const session = createSession(agentId, options);
@@ -35608,17 +35707,36 @@ async function prompt(message, agentId, options = {}) {
35608
35707
  }
35609
35708
  }
35610
35709
  function query(params) {
35611
- return new LettaAgentClient({
35710
+ const client = new LettaAgentClient({
35612
35711
  backend: "local",
35613
35712
  appServer: { harnessBackend: "api" }
35614
- }).query(params);
35713
+ });
35714
+ const inner = client.query(params);
35715
+ const result = async function* () {
35716
+ try {
35717
+ yield* inner;
35718
+ } finally {
35719
+ await client.close();
35720
+ }
35721
+ }();
35722
+ return Object.defineProperties(Object.assign(result, {
35723
+ interrupt: () => inner.interrupt(),
35724
+ close() {
35725
+ inner.close();
35726
+ client.close();
35727
+ result.return();
35728
+ }
35729
+ }), {
35730
+ conversationId: { get: () => inner.conversationId, enumerable: true },
35731
+ agentId: { get: () => inner.agentId, enumerable: true }
35732
+ });
35615
35733
  }
35616
35734
  async function listMessagesDirect(agentId, options = {}) {
35617
- const session = new LettaAgentClient().resumeSession(agentId, {
35735
+ const session = resumeSession(agentId, {
35618
35736
  permissionMode: "unrestricted"
35619
35737
  });
35620
- await session.initialize();
35621
35738
  try {
35739
+ await session.initialize();
35622
35740
  return await session.listMessages(options);
35623
35741
  } finally {
35624
35742
  session.close();
@@ -35681,4 +35799,4 @@ export {
35681
35799
  CloudManagedSandboxExpiredError
35682
35800
  };
35683
35801
 
35684
- //# debugId=521C138A96EC8F7F64756E2164756E21
35802
+ //# debugId=449C4232C4B789D064756E2164756E21