@letta-ai/letta-code 0.31.8 → 0.31.10

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/letta.js CHANGED
@@ -3757,29 +3757,6 @@ var init_oauth = __esm(() => {
3757
3757
  };
3758
3758
  });
3759
3759
 
3760
- // src/auth/oauth-refresh.ts
3761
- async function refreshAccessTokenSingleFlight(refreshToken2, deviceId, deviceName, refresh = refreshAccessToken2) {
3762
- const refreshKey = `${refreshToken2}\x00${deviceId}`;
3763
- const existing = inFlightRefreshes.get(refreshKey);
3764
- if (existing) {
3765
- return await existing;
3766
- }
3767
- const pending = refresh(refreshToken2, deviceId, deviceName);
3768
- inFlightRefreshes.set(refreshKey, pending);
3769
- try {
3770
- return await pending;
3771
- } finally {
3772
- if (inFlightRefreshes.get(refreshKey) === pending) {
3773
- inFlightRefreshes.delete(refreshKey);
3774
- }
3775
- }
3776
- }
3777
- var inFlightRefreshes;
3778
- var init_oauth_refresh = __esm(() => {
3779
- init_oauth();
3780
- inFlightRefreshes = new Map;
3781
- });
3782
-
3783
3760
  // src/agent/agent-id.ts
3784
3761
  function isLocalAgentId(agentId) {
3785
3762
  return agentId.startsWith("agent-local-");
@@ -5418,98 +5395,12 @@ var init_settings_manager = __esm(() => {
5418
5395
  settingsManager = globalThis.__lettaSettingsManager;
5419
5396
  });
5420
5397
 
5421
- // src/utils/timing.ts
5422
- function isTimingsEnabled() {
5423
- const val = process.env.LETTA_DEBUG_TIMINGS;
5424
- return val === "1" || val === "true";
5425
- }
5426
- function formatDuration(ms) {
5427
- if (ms < 1000)
5428
- return `${Math.round(ms)}ms`;
5429
- return `${(ms / 1000).toFixed(2)}s`;
5430
- }
5431
- function formatTimestamp(date) {
5432
- return date.toISOString().slice(11, 23);
5433
- }
5434
- function logTiming(message) {
5435
- if (isTimingsEnabled()) {
5436
- console.error(`[timing] ${message}`);
5437
- }
5438
- }
5439
- function markMilestone(name) {
5440
- const now = performance.now();
5441
- milestones.set(name, now);
5442
- if (firstMilestoneTime === null) {
5443
- firstMilestoneTime = now;
5444
- }
5445
- if (isTimingsEnabled()) {
5446
- const relative = now - firstMilestoneTime;
5447
- console.error(`[timing] MILESTONE ${name} at +${formatDuration(relative)} (${formatTimestamp(new Date)})`);
5448
- }
5449
- }
5450
- function measureSinceMilestone(label, fromMilestone) {
5451
- if (!isTimingsEnabled())
5452
- return;
5453
- const startTime = milestones.get(fromMilestone);
5454
- if (startTime === undefined) {
5455
- console.error(`[timing] WARNING: milestone "${fromMilestone}" not found for measurement "${label}"`);
5456
- return;
5457
- }
5458
- const duration = performance.now() - startTime;
5459
- console.error(`[timing] ${label}: ${formatDuration(duration)}`);
5460
- }
5461
- function reportAllMilestones() {
5462
- if (!isTimingsEnabled() || milestones.size === 0)
5463
- return;
5464
- const first = firstMilestoneTime ?? 0;
5465
- console.error(`[timing] ======== MILESTONE SUMMARY ========`);
5466
- const sorted = [...milestones.entries()].sort((a, b) => a[1] - b[1]);
5467
- let prevTime = first;
5468
- for (const [name, time] of sorted) {
5469
- const relativeToStart = time - first;
5470
- const delta = time - prevTime;
5471
- const deltaStr = prevTime === first ? "" : ` (+${formatDuration(delta)})`;
5472
- console.error(`[timing] +${formatDuration(relativeToStart).padStart(8)} ${name}${deltaStr}`);
5473
- prevTime = time;
5474
- }
5475
- console.error(`[timing] =====================================`);
5476
- }
5477
- function createTimingFetch(baseFetch) {
5478
- return async (input, init) => {
5479
- const start = performance.now();
5480
- const startTime = formatTimestamp(new Date);
5481
- const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
5482
- const method = init?.method || "GET";
5483
- let path2;
5484
- try {
5485
- path2 = new URL(url).pathname;
5486
- } catch {
5487
- path2 = url;
5488
- }
5489
- logTiming(`${method} ${path2} started at ${startTime}`);
5490
- try {
5491
- const response = await baseFetch(input, init);
5492
- const duration = performance.now() - start;
5493
- logTiming(`${method} ${path2} -> ${formatDuration(duration)} (status: ${response.status})`);
5494
- return response;
5495
- } catch (error) {
5496
- const duration = performance.now() - start;
5497
- logTiming(`${method} ${path2} -> FAILED after ${formatDuration(duration)}`);
5498
- throw error;
5499
- }
5500
- };
5501
- }
5502
- var milestones, firstMilestoneTime = null;
5503
- var init_timing = __esm(() => {
5504
- milestones = new Map;
5505
- });
5506
-
5507
5398
  // package.json
5508
5399
  var package_default;
5509
5400
  var init_package = __esm(() => {
5510
5401
  package_default = {
5511
5402
  name: "@letta-ai/letta-code",
5512
- version: "0.31.8",
5403
+ version: "0.31.10",
5513
5404
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5514
5405
  type: "module",
5515
5406
  packageManager: "bun@1.3.10",
@@ -5753,266 +5644,6 @@ var init_package = __esm(() => {
5753
5644
  };
5754
5645
  });
5755
5646
 
5756
- // src/backend/api/memfs-git-proxy.ts
5757
- var exports_memfs_git_proxy = {};
5758
- __export(exports_memfs_git_proxy, {
5759
- getMemfsServerUrl: () => getMemfsServerUrl,
5760
- getMemfsGitProxyRewriteConfig: () => getMemfsGitProxyRewriteConfig,
5761
- LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV: () => LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV
5762
- });
5763
- function isLocalhostUrl(value) {
5764
- if (!value)
5765
- return false;
5766
- try {
5767
- const parsed = new URL(value);
5768
- return ["localhost", "127.0.0.1", "::1", "[::1]"].includes(parsed.hostname);
5769
- } catch {
5770
- return false;
5771
- }
5772
- }
5773
- function trimBaseUrl(value) {
5774
- return value.trim().replace(/\/+$/, "");
5775
- }
5776
- function getMemfsServerUrl() {
5777
- let settings = null;
5778
- try {
5779
- settings = settingsManager.getSettings();
5780
- } catch {}
5781
- const configuredMemfsUrl = process.env.LETTA_MEMFS_BASE_URL || settings?.env?.LETTA_MEMFS_BASE_URL;
5782
- if (configuredMemfsUrl) {
5783
- return configuredMemfsUrl;
5784
- }
5785
- return LETTA_CLOUD_API_URL;
5786
- }
5787
- function getMemfsGitProxyRewriteConfig(env = process.env) {
5788
- const rawProxyBaseUrl = env[LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV]?.trim();
5789
- if (!rawProxyBaseUrl || !isLocalhostUrl(rawProxyBaseUrl)) {
5790
- return null;
5791
- }
5792
- const memfsBaseUrl = trimBaseUrl(getMemfsServerUrl());
5793
- if (!memfsBaseUrl.includes("api.letta.com")) {
5794
- return null;
5795
- }
5796
- const proxyBaseUrl = trimBaseUrl(rawProxyBaseUrl);
5797
- const proxyPrefix = `${proxyBaseUrl}/v1/git/`;
5798
- const memfsPrefix = `${memfsBaseUrl}/v1/git/`;
5799
- return {
5800
- proxyBaseUrl,
5801
- memfsBaseUrl,
5802
- proxyPrefix,
5803
- memfsPrefix,
5804
- configKey: `url.${proxyPrefix}.insteadOf`,
5805
- configValue: memfsPrefix
5806
- };
5807
- }
5808
- var LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV = "LETTA_MEMFS_GIT_PROXY_BASE_URL";
5809
- var init_memfs_git_proxy = __esm(() => {
5810
- init_oauth();
5811
- init_settings_manager();
5812
- });
5813
-
5814
- // src/backend/api/client.ts
5815
- var exports_client = {};
5816
- __export(exports_client, {
5817
- getServerUrl: () => getServerUrl,
5818
- getRuntimeEnvironmentDeviceId: () => getRuntimeEnvironmentDeviceId,
5819
- getMemfsServerUrl: () => getMemfsServerUrl,
5820
- getMemfsGitProxyRewriteConfig: () => getMemfsGitProxyRewriteConfig,
5821
- getClientDefaultHeaders: () => getClientDefaultHeaders,
5822
- getClient: () => getClient,
5823
- consumeLastSDKDiagnostic: () => consumeLastSDKDiagnostic,
5824
- clearLastSDKDiagnostic: () => clearLastSDKDiagnostic,
5825
- __testOverrideGetClient: () => __testOverrideGetClient,
5826
- LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV: () => LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV
5827
- });
5828
- import { hostname } from "node:os";
5829
- function __testOverrideGetClient(factory) {
5830
- _testClientOverride = factory;
5831
- }
5832
- function safeDiagnosticString(value) {
5833
- if (value === null || value === undefined) {
5834
- return "";
5835
- }
5836
- if (typeof value === "string") {
5837
- return value;
5838
- }
5839
- try {
5840
- return JSON.stringify(value);
5841
- } catch {
5842
- return String(value);
5843
- }
5844
- }
5845
- function truncateDiagnostic(value) {
5846
- const text = safeDiagnosticString(value);
5847
- if (text.length <= SDK_DIAGNOSTIC_MAX_LEN) {
5848
- return text;
5849
- }
5850
- return `${text.slice(0, SDK_DIAGNOSTIC_MAX_LEN)}...[truncated, was ${text.length}b]`;
5851
- }
5852
- function captureSDKErrorDiagnostic(args) {
5853
- const diagnosticLine = truncateDiagnostic(args.map((arg) => safeDiagnosticString(arg)).join(" "));
5854
- const previous = lastSDKDiagnostic ?? { lines: [] };
5855
- lastSDKDiagnostic = {
5856
- lines: [...previous.lines, diagnosticLine].slice(-SDK_DIAGNOSTIC_MAX_LINES)
5857
- };
5858
- }
5859
- function consumeLastSDKDiagnostic() {
5860
- const diag = lastSDKDiagnostic;
5861
- lastSDKDiagnostic = null;
5862
- if (!diag || diag.lines.length === 0) {
5863
- return null;
5864
- }
5865
- return `sdk_error=${diag.lines.join(" || ")}`;
5866
- }
5867
- function clearLastSDKDiagnostic() {
5868
- lastSDKDiagnostic = null;
5869
- }
5870
- function getServerUrl() {
5871
- const settings = settingsManager.getSettings();
5872
- return process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
5873
- }
5874
- function getNodeRoutingHeader() {
5875
- const raw = process.env.LETTA_NODE;
5876
- if (raw === undefined || raw.trim() === "") {
5877
- return {};
5878
- }
5879
- const enabled = NODE_HEADER_ENABLED_VALUES.has(raw.trim().toLowerCase());
5880
- return { "x-letta-node": enabled ? "1" : "0" };
5881
- }
5882
- function getRuntimeEnvironmentDeviceId() {
5883
- return process.env[RUNTIME_ENVIRONMENT_DEVICE_ID_ENV]?.trim() || settingsManager.getOrCreateDeviceId();
5884
- }
5885
- function getClientDefaultHeaders() {
5886
- return {
5887
- "X-Letta-Source": "letta-code",
5888
- "User-Agent": `letta-code/${package_default.version}`,
5889
- "X-Letta-Environment-Device-Id": getRuntimeEnvironmentDeviceId(),
5890
- ...getNodeRoutingHeader(),
5891
- ...process.env.LETTA_MEMFS_BACKEND === "hosted" ? { "x-letta-memfs-backend": "hosted" } : {}
5892
- };
5893
- }
5894
- async function getClient() {
5895
- if (_testClientOverride) {
5896
- return await _testClientOverride();
5897
- }
5898
- const baseSettings = settingsManager.getSettings();
5899
- const cachedTokens = settingsManager.getCachedSecureTokens();
5900
- const cachedSettings = {
5901
- ...baseSettings,
5902
- env: {
5903
- ...baseSettings.env,
5904
- ...cachedTokens.apiKey && { LETTA_API_KEY: cachedTokens.apiKey }
5905
- },
5906
- refreshToken: cachedTokens.refreshToken ?? baseSettings.refreshToken
5907
- };
5908
- const settings = process.env.LETTA_API_KEY || cachedSettings.env?.LETTA_API_KEY || cachedSettings.refreshToken ? cachedSettings : await settingsManager.getSettingsWithSecureTokens();
5909
- let apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
5910
- if (!process.env.LETTA_API_KEY) {
5911
- if (apiKey) {
5912
- _cachedApiKey = apiKey;
5913
- } else if (_cachedApiKey) {
5914
- apiKey = _cachedApiKey;
5915
- }
5916
- }
5917
- if (!process.env.LETTA_API_KEY && settings.tokenExpiresAt && settings.refreshToken) {
5918
- const now = Date.now();
5919
- const expiresAt = settings.tokenExpiresAt;
5920
- if (!apiKey || expiresAt - now < 5 * 60 * 1000) {
5921
- try {
5922
- const deviceId = settingsManager.getOrCreateDeviceId();
5923
- const deviceName = hostname();
5924
- const tokens = await refreshAccessTokenSingleFlight(settings.refreshToken, deviceId, deviceName);
5925
- settingsManager.updateSettings({
5926
- env: { LETTA_API_KEY: tokens.access_token },
5927
- refreshToken: tokens.refresh_token || settings.refreshToken,
5928
- tokenExpiresAt: now + tokens.expires_in * 1000
5929
- });
5930
- apiKey = tokens.access_token;
5931
- _cachedApiKey = tokens.access_token;
5932
- } catch (error) {
5933
- trackBoundaryError({
5934
- errorType: "auth_token_refresh_failed",
5935
- error,
5936
- context: "auth_client_token_refresh"
5937
- });
5938
- console.error("Failed to refresh access token:", error);
5939
- console.error(`
5940
- If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, and re-run 'letta' to re-authenticate`);
5941
- throw new Error(`Failed to refresh access token: ${error instanceof Error ? error.message : String(error)}`);
5942
- }
5943
- }
5944
- }
5945
- const baseURL = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
5946
- if (!apiKey && baseURL === LETTA_CLOUD_API_URL) {
5947
- console.error("Missing LETTA_API_KEY");
5948
- console.error("Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key");
5949
- console.error(new Error("getClient() called without credentials").stack);
5950
- throw new Error("Missing LETTA_API_KEY. Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key.");
5951
- }
5952
- const client = new Letta({
5953
- apiKey,
5954
- baseURL,
5955
- logger: sdkLogger,
5956
- timeout: Number(process.env.LETTA_REQUEST_TIMEOUT_MS) || 10 * 60 * 1000,
5957
- defaultHeaders: getClientDefaultHeaders(),
5958
- ...isTimingsEnabled() && { fetch: createTimingFetch(fetch) }
5959
- });
5960
- const MESSAGE_CACHE_MAX = 32;
5961
- const messageCache = new Map;
5962
- const origRetrieveMessage = client.messages.retrieve.bind(client.messages);
5963
- client.messages.retrieve = (...args) => {
5964
- const messageId = args[0];
5965
- const cached = messageCache.get(messageId);
5966
- if (cached) {
5967
- messageCache.delete(messageId);
5968
- messageCache.set(messageId, cached);
5969
- return cached;
5970
- }
5971
- const promise = origRetrieveMessage(...args);
5972
- messageCache.set(messageId, promise);
5973
- if (messageCache.size > MESSAGE_CACHE_MAX) {
5974
- const oldest = messageCache.keys().next().value;
5975
- if (oldest !== undefined)
5976
- messageCache.delete(oldest);
5977
- }
5978
- promise.catch(() => messageCache.delete(messageId));
5979
- return promise;
5980
- };
5981
- return client;
5982
- }
5983
- var SDK_DIAGNOSTIC_MAX_LEN = 400, SDK_DIAGNOSTIC_MAX_LINES = 4, lastSDKDiagnostic = null, _cachedApiKey, _testClientOverride = null, sdkLogger, NODE_HEADER_ENABLED_VALUES, RUNTIME_ENVIRONMENT_DEVICE_ID_ENV = "LETTA_RUNTIME_ENVIRONMENT_DEVICE_ID";
5984
- var init_client2 = __esm(() => {
5985
- init_letta_client();
5986
- init_oauth();
5987
- init_oauth_refresh();
5988
- init_settings_manager();
5989
- init_error_reporting();
5990
- init_debug();
5991
- init_timing();
5992
- init_package();
5993
- init_memfs_git_proxy();
5994
- sdkLogger = {
5995
- error: (...args) => {
5996
- try {
5997
- captureSDKErrorDiagnostic(args);
5998
- } catch {}
5999
- if (isDebugEnabled()) {
6000
- console.error(...args);
6001
- }
6002
- },
6003
- warn: (...args) => {
6004
- console.warn(...args);
6005
- },
6006
- info: (...args) => {
6007
- console.info(...args);
6008
- },
6009
- debug: (...args) => {
6010
- console.debug(...args);
6011
- }
6012
- };
6013
- NODE_HEADER_ENABLED_VALUES = new Set(["1", "true", "yes"]);
6014
- });
6015
-
6016
5647
  // src/backend/api/http-headers.ts
6017
5648
  function getLettaCodeHeaders(apiKey) {
6018
5649
  return {
@@ -6140,8 +5771,8 @@ function parseUrl(value, options = {}) {
6140
5771
  return null;
6141
5772
  }
6142
5773
  }
6143
- function isLoopbackHostname(hostname2) {
6144
- const normalized = hostname2.toLowerCase();
5774
+ function isLoopbackHostname(hostname) {
5775
+ const normalized = hostname.toLowerCase();
6145
5776
  return normalized === "localhost" || normalized === "0.0.0.0" || normalized === "::1" || normalized === "[::1]" || normalized.startsWith("127.");
6146
5777
  }
6147
5778
  function isLoopbackUrl(value, options = {}) {
@@ -6198,6 +5829,38 @@ var init_metadata = __esm(() => {
6198
5829
  init_request();
6199
5830
  });
6200
5831
 
5832
+ // src/backend/api/server-url.ts
5833
+ var exports_server_url = {};
5834
+ __export(exports_server_url, {
5835
+ isCloudServerUrl: () => isCloudServerUrl,
5836
+ getServerUrl: () => getServerUrl
5837
+ });
5838
+ function getServerUrl() {
5839
+ const settings = settingsManager.getSettings();
5840
+ return process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
5841
+ }
5842
+ function isCloudServerUrl(serverUrl) {
5843
+ let resolved = serverUrl;
5844
+ if (resolved === undefined) {
5845
+ try {
5846
+ resolved = getServerUrl();
5847
+ } catch {
5848
+ resolved = process.env.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
5849
+ }
5850
+ }
5851
+ try {
5852
+ const parsed = new URL(resolved);
5853
+ const cloud = new URL(LETTA_CLOUD_API_URL);
5854
+ return parsed.hostname === cloud.hostname;
5855
+ } catch {
5856
+ return false;
5857
+ }
5858
+ }
5859
+ var init_server_url = __esm(() => {
5860
+ init_oauth();
5861
+ init_settings_manager();
5862
+ });
5863
+
6201
5864
  // src/version.ts
6202
5865
  var exports_version = {};
6203
5866
  __export(exports_version, {
@@ -6725,9 +6388,9 @@ class TelemetryManager {
6725
6388
  var telemetry;
6726
6389
  var init_telemetry = __esm(() => {
6727
6390
  init_oauth();
6728
- init_client2();
6729
6391
  init_health();
6730
6392
  init_metadata();
6393
+ init_server_url();
6731
6394
  init_paths();
6732
6395
  init_settings_manager();
6733
6396
  init_debug();
@@ -6776,6 +6439,370 @@ function buildCreatedAgentTags(options = {}) {
6776
6439
  }
6777
6440
  var LETTA_CODE_ORIGIN_TAG = "origin:letta-code", ONBOARDING_ORIGIN_TAG = "origin:onboarding", LETTA_CODE_SUBAGENT_TAG = "role:subagent", GIT_MEMORY_ENABLED_TAG = "git-memory-enabled";
6778
6441
 
6442
+ // src/auth/oauth-refresh.ts
6443
+ async function refreshAccessTokenSingleFlight(refreshToken2, deviceId, deviceName, refresh = refreshAccessToken2) {
6444
+ const refreshKey = `${refreshToken2}\x00${deviceId}`;
6445
+ const existing = inFlightRefreshes.get(refreshKey);
6446
+ if (existing) {
6447
+ return await existing;
6448
+ }
6449
+ const pending = refresh(refreshToken2, deviceId, deviceName);
6450
+ inFlightRefreshes.set(refreshKey, pending);
6451
+ try {
6452
+ return await pending;
6453
+ } finally {
6454
+ if (inFlightRefreshes.get(refreshKey) === pending) {
6455
+ inFlightRefreshes.delete(refreshKey);
6456
+ }
6457
+ }
6458
+ }
6459
+ var inFlightRefreshes;
6460
+ var init_oauth_refresh = __esm(() => {
6461
+ init_oauth();
6462
+ inFlightRefreshes = new Map;
6463
+ });
6464
+
6465
+ // src/utils/timing.ts
6466
+ function isTimingsEnabled() {
6467
+ const val = process.env.LETTA_DEBUG_TIMINGS;
6468
+ return val === "1" || val === "true";
6469
+ }
6470
+ function formatDuration(ms) {
6471
+ if (ms < 1000)
6472
+ return `${Math.round(ms)}ms`;
6473
+ return `${(ms / 1000).toFixed(2)}s`;
6474
+ }
6475
+ function formatTimestamp(date) {
6476
+ return date.toISOString().slice(11, 23);
6477
+ }
6478
+ function logTiming(message) {
6479
+ if (isTimingsEnabled()) {
6480
+ console.error(`[timing] ${message}`);
6481
+ }
6482
+ }
6483
+ function markMilestone(name) {
6484
+ const now = performance.now();
6485
+ milestones.set(name, now);
6486
+ if (firstMilestoneTime === null) {
6487
+ firstMilestoneTime = now;
6488
+ }
6489
+ if (isTimingsEnabled()) {
6490
+ const relative = now - firstMilestoneTime;
6491
+ console.error(`[timing] MILESTONE ${name} at +${formatDuration(relative)} (${formatTimestamp(new Date)})`);
6492
+ }
6493
+ }
6494
+ function measureSinceMilestone(label, fromMilestone) {
6495
+ if (!isTimingsEnabled())
6496
+ return;
6497
+ const startTime = milestones.get(fromMilestone);
6498
+ if (startTime === undefined) {
6499
+ console.error(`[timing] WARNING: milestone "${fromMilestone}" not found for measurement "${label}"`);
6500
+ return;
6501
+ }
6502
+ const duration = performance.now() - startTime;
6503
+ console.error(`[timing] ${label}: ${formatDuration(duration)}`);
6504
+ }
6505
+ function reportAllMilestones() {
6506
+ if (!isTimingsEnabled() || milestones.size === 0)
6507
+ return;
6508
+ const first = firstMilestoneTime ?? 0;
6509
+ console.error(`[timing] ======== MILESTONE SUMMARY ========`);
6510
+ const sorted = [...milestones.entries()].sort((a, b) => a[1] - b[1]);
6511
+ let prevTime = first;
6512
+ for (const [name, time] of sorted) {
6513
+ const relativeToStart = time - first;
6514
+ const delta = time - prevTime;
6515
+ const deltaStr = prevTime === first ? "" : ` (+${formatDuration(delta)})`;
6516
+ console.error(`[timing] +${formatDuration(relativeToStart).padStart(8)} ${name}${deltaStr}`);
6517
+ prevTime = time;
6518
+ }
6519
+ console.error(`[timing] =====================================`);
6520
+ }
6521
+ function createTimingFetch(baseFetch) {
6522
+ return async (input, init) => {
6523
+ const start = performance.now();
6524
+ const startTime = formatTimestamp(new Date);
6525
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
6526
+ const method = init?.method || "GET";
6527
+ let path2;
6528
+ try {
6529
+ path2 = new URL(url).pathname;
6530
+ } catch {
6531
+ path2 = url;
6532
+ }
6533
+ logTiming(`${method} ${path2} started at ${startTime}`);
6534
+ try {
6535
+ const response = await baseFetch(input, init);
6536
+ const duration = performance.now() - start;
6537
+ logTiming(`${method} ${path2} -> ${formatDuration(duration)} (status: ${response.status})`);
6538
+ return response;
6539
+ } catch (error) {
6540
+ const duration = performance.now() - start;
6541
+ logTiming(`${method} ${path2} -> FAILED after ${formatDuration(duration)}`);
6542
+ throw error;
6543
+ }
6544
+ };
6545
+ }
6546
+ var milestones, firstMilestoneTime = null;
6547
+ var init_timing = __esm(() => {
6548
+ milestones = new Map;
6549
+ });
6550
+
6551
+ // src/backend/api/memfs-git-proxy.ts
6552
+ var exports_memfs_git_proxy = {};
6553
+ __export(exports_memfs_git_proxy, {
6554
+ getMemfsServerUrl: () => getMemfsServerUrl,
6555
+ getMemfsGitProxyRewriteConfig: () => getMemfsGitProxyRewriteConfig,
6556
+ LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV: () => LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV
6557
+ });
6558
+ function isLocalhostUrl(value) {
6559
+ if (!value)
6560
+ return false;
6561
+ try {
6562
+ const parsed = new URL(value);
6563
+ return ["localhost", "127.0.0.1", "::1", "[::1]"].includes(parsed.hostname);
6564
+ } catch {
6565
+ return false;
6566
+ }
6567
+ }
6568
+ function trimBaseUrl(value) {
6569
+ return value.trim().replace(/\/+$/, "");
6570
+ }
6571
+ function getMemfsServerUrl() {
6572
+ let settings = null;
6573
+ try {
6574
+ settings = settingsManager.getSettings();
6575
+ } catch {}
6576
+ const configuredMemfsUrl = process.env.LETTA_MEMFS_BASE_URL || settings?.env?.LETTA_MEMFS_BASE_URL;
6577
+ if (configuredMemfsUrl) {
6578
+ return configuredMemfsUrl;
6579
+ }
6580
+ return LETTA_CLOUD_API_URL;
6581
+ }
6582
+ function getMemfsGitProxyRewriteConfig(env = process.env) {
6583
+ const rawProxyBaseUrl = env[LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV]?.trim();
6584
+ if (!rawProxyBaseUrl || !isLocalhostUrl(rawProxyBaseUrl)) {
6585
+ return null;
6586
+ }
6587
+ const memfsBaseUrl = trimBaseUrl(getMemfsServerUrl());
6588
+ if (!memfsBaseUrl.includes("api.letta.com")) {
6589
+ return null;
6590
+ }
6591
+ const proxyBaseUrl = trimBaseUrl(rawProxyBaseUrl);
6592
+ const proxyPrefix = `${proxyBaseUrl}/v1/git/`;
6593
+ const memfsPrefix = `${memfsBaseUrl}/v1/git/`;
6594
+ return {
6595
+ proxyBaseUrl,
6596
+ memfsBaseUrl,
6597
+ proxyPrefix,
6598
+ memfsPrefix,
6599
+ configKey: `url.${proxyPrefix}.insteadOf`,
6600
+ configValue: memfsPrefix
6601
+ };
6602
+ }
6603
+ var LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV = "LETTA_MEMFS_GIT_PROXY_BASE_URL";
6604
+ var init_memfs_git_proxy = __esm(() => {
6605
+ init_oauth();
6606
+ init_settings_manager();
6607
+ });
6608
+
6609
+ // src/backend/api/client.ts
6610
+ var exports_client = {};
6611
+ __export(exports_client, {
6612
+ getRuntimeEnvironmentDeviceId: () => getRuntimeEnvironmentDeviceId,
6613
+ getMemfsServerUrl: () => getMemfsServerUrl,
6614
+ getMemfsGitProxyRewriteConfig: () => getMemfsGitProxyRewriteConfig,
6615
+ getClientDefaultHeaders: () => getClientDefaultHeaders,
6616
+ getClient: () => getClient,
6617
+ consumeLastSDKDiagnostic: () => consumeLastSDKDiagnostic,
6618
+ clearLastSDKDiagnostic: () => clearLastSDKDiagnostic,
6619
+ __testOverrideGetClient: () => __testOverrideGetClient,
6620
+ LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV: () => LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV
6621
+ });
6622
+ import { hostname } from "node:os";
6623
+ function __testOverrideGetClient(factory) {
6624
+ _testClientOverride = factory;
6625
+ }
6626
+ function safeDiagnosticString(value) {
6627
+ if (value === null || value === undefined) {
6628
+ return "";
6629
+ }
6630
+ if (typeof value === "string") {
6631
+ return value;
6632
+ }
6633
+ try {
6634
+ return JSON.stringify(value);
6635
+ } catch {
6636
+ return String(value);
6637
+ }
6638
+ }
6639
+ function truncateDiagnostic(value) {
6640
+ const text = safeDiagnosticString(value);
6641
+ if (text.length <= SDK_DIAGNOSTIC_MAX_LEN) {
6642
+ return text;
6643
+ }
6644
+ return `${text.slice(0, SDK_DIAGNOSTIC_MAX_LEN)}...[truncated, was ${text.length}b]`;
6645
+ }
6646
+ function captureSDKErrorDiagnostic(args) {
6647
+ const diagnosticLine = truncateDiagnostic(args.map((arg) => safeDiagnosticString(arg)).join(" "));
6648
+ const previous = lastSDKDiagnostic ?? { lines: [] };
6649
+ lastSDKDiagnostic = {
6650
+ lines: [...previous.lines, diagnosticLine].slice(-SDK_DIAGNOSTIC_MAX_LINES)
6651
+ };
6652
+ }
6653
+ function consumeLastSDKDiagnostic() {
6654
+ const diag = lastSDKDiagnostic;
6655
+ lastSDKDiagnostic = null;
6656
+ if (!diag || diag.lines.length === 0) {
6657
+ return null;
6658
+ }
6659
+ return `sdk_error=${diag.lines.join(" || ")}`;
6660
+ }
6661
+ function clearLastSDKDiagnostic() {
6662
+ lastSDKDiagnostic = null;
6663
+ }
6664
+ function getNodeRoutingHeader() {
6665
+ const raw = process.env.LETTA_NODE;
6666
+ if (raw === undefined || raw.trim() === "") {
6667
+ return {};
6668
+ }
6669
+ const enabled = NODE_HEADER_ENABLED_VALUES.has(raw.trim().toLowerCase());
6670
+ return { "x-letta-node": enabled ? "1" : "0" };
6671
+ }
6672
+ function getRuntimeEnvironmentDeviceId() {
6673
+ return process.env[RUNTIME_ENVIRONMENT_DEVICE_ID_ENV]?.trim() || settingsManager.getOrCreateDeviceId();
6674
+ }
6675
+ function getClientDefaultHeaders() {
6676
+ return {
6677
+ "X-Letta-Source": "letta-code",
6678
+ "User-Agent": `letta-code/${package_default.version}`,
6679
+ "X-Letta-Environment-Device-Id": getRuntimeEnvironmentDeviceId(),
6680
+ ...getNodeRoutingHeader(),
6681
+ ...process.env.LETTA_MEMFS_BACKEND === "hosted" ? { "x-letta-memfs-backend": "hosted" } : {}
6682
+ };
6683
+ }
6684
+ async function getClient() {
6685
+ if (_testClientOverride) {
6686
+ return await _testClientOverride();
6687
+ }
6688
+ const baseSettings = settingsManager.getSettings();
6689
+ const cachedTokens = settingsManager.getCachedSecureTokens();
6690
+ const cachedSettings = {
6691
+ ...baseSettings,
6692
+ env: {
6693
+ ...baseSettings.env,
6694
+ ...cachedTokens.apiKey && { LETTA_API_KEY: cachedTokens.apiKey }
6695
+ },
6696
+ refreshToken: cachedTokens.refreshToken ?? baseSettings.refreshToken
6697
+ };
6698
+ const settings = process.env.LETTA_API_KEY || cachedSettings.env?.LETTA_API_KEY || cachedSettings.refreshToken ? cachedSettings : await settingsManager.getSettingsWithSecureTokens();
6699
+ let apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
6700
+ if (!process.env.LETTA_API_KEY) {
6701
+ if (apiKey) {
6702
+ _cachedApiKey = apiKey;
6703
+ } else if (_cachedApiKey) {
6704
+ apiKey = _cachedApiKey;
6705
+ }
6706
+ }
6707
+ if (!process.env.LETTA_API_KEY && settings.tokenExpiresAt && settings.refreshToken) {
6708
+ const now = Date.now();
6709
+ const expiresAt = settings.tokenExpiresAt;
6710
+ if (!apiKey || expiresAt - now < 5 * 60 * 1000) {
6711
+ try {
6712
+ const deviceId = settingsManager.getOrCreateDeviceId();
6713
+ const deviceName = hostname();
6714
+ const tokens = await refreshAccessTokenSingleFlight(settings.refreshToken, deviceId, deviceName);
6715
+ settingsManager.updateSettings({
6716
+ env: { LETTA_API_KEY: tokens.access_token },
6717
+ refreshToken: tokens.refresh_token || settings.refreshToken,
6718
+ tokenExpiresAt: now + tokens.expires_in * 1000
6719
+ });
6720
+ apiKey = tokens.access_token;
6721
+ _cachedApiKey = tokens.access_token;
6722
+ } catch (error) {
6723
+ trackBoundaryError({
6724
+ errorType: "auth_token_refresh_failed",
6725
+ error,
6726
+ context: "auth_client_token_refresh"
6727
+ });
6728
+ console.error("Failed to refresh access token:", error);
6729
+ console.error(`
6730
+ If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, and re-run 'letta' to re-authenticate`);
6731
+ throw new Error(`Failed to refresh access token: ${error instanceof Error ? error.message : String(error)}`);
6732
+ }
6733
+ }
6734
+ }
6735
+ const baseURL = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
6736
+ if (!apiKey && baseURL === LETTA_CLOUD_API_URL) {
6737
+ console.error("Missing LETTA_API_KEY");
6738
+ console.error("Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key");
6739
+ console.error(new Error("getClient() called without credentials").stack);
6740
+ throw new Error("Missing LETTA_API_KEY. Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key.");
6741
+ }
6742
+ const client = new Letta({
6743
+ apiKey,
6744
+ baseURL,
6745
+ logger: sdkLogger,
6746
+ timeout: Number(process.env.LETTA_REQUEST_TIMEOUT_MS) || 10 * 60 * 1000,
6747
+ defaultHeaders: getClientDefaultHeaders(),
6748
+ ...isTimingsEnabled() && { fetch: createTimingFetch(fetch) }
6749
+ });
6750
+ const MESSAGE_CACHE_MAX = 32;
6751
+ const messageCache = new Map;
6752
+ const origRetrieveMessage = client.messages.retrieve.bind(client.messages);
6753
+ client.messages.retrieve = (...args) => {
6754
+ const messageId = args[0];
6755
+ const cached = messageCache.get(messageId);
6756
+ if (cached) {
6757
+ messageCache.delete(messageId);
6758
+ messageCache.set(messageId, cached);
6759
+ return cached;
6760
+ }
6761
+ const promise = origRetrieveMessage(...args);
6762
+ messageCache.set(messageId, promise);
6763
+ if (messageCache.size > MESSAGE_CACHE_MAX) {
6764
+ const oldest = messageCache.keys().next().value;
6765
+ if (oldest !== undefined)
6766
+ messageCache.delete(oldest);
6767
+ }
6768
+ promise.catch(() => messageCache.delete(messageId));
6769
+ return promise;
6770
+ };
6771
+ return client;
6772
+ }
6773
+ var SDK_DIAGNOSTIC_MAX_LEN = 400, SDK_DIAGNOSTIC_MAX_LINES = 4, lastSDKDiagnostic = null, _cachedApiKey, _testClientOverride = null, sdkLogger, NODE_HEADER_ENABLED_VALUES, RUNTIME_ENVIRONMENT_DEVICE_ID_ENV = "LETTA_RUNTIME_ENVIRONMENT_DEVICE_ID";
6774
+ var init_client2 = __esm(() => {
6775
+ init_letta_client();
6776
+ init_oauth();
6777
+ init_oauth_refresh();
6778
+ init_settings_manager();
6779
+ init_error_reporting();
6780
+ init_debug();
6781
+ init_timing();
6782
+ init_package();
6783
+ init_memfs_git_proxy();
6784
+ sdkLogger = {
6785
+ error: (...args) => {
6786
+ try {
6787
+ captureSDKErrorDiagnostic(args);
6788
+ } catch {}
6789
+ if (isDebugEnabled()) {
6790
+ console.error(...args);
6791
+ }
6792
+ },
6793
+ warn: (...args) => {
6794
+ console.warn(...args);
6795
+ },
6796
+ info: (...args) => {
6797
+ console.info(...args);
6798
+ },
6799
+ debug: (...args) => {
6800
+ console.debug(...args);
6801
+ }
6802
+ };
6803
+ NODE_HEADER_ENABLED_VALUES = new Set(["1", "true", "yes"]);
6804
+ });
6805
+
6779
6806
  // src/utils/text-files.ts
6780
6807
  import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
6781
6808
  function getUtf16Bom(bytes) {
@@ -88170,6 +88197,30 @@ var init_tool_return_clamp = __esm(() => {
88170
88197
  init_truncation();
88171
88198
  });
88172
88199
 
88200
+ // src/tools/task-tool-assets.ts
88201
+ function stripComputerFromTaskSchema(schema5) {
88202
+ const properties4 = schema5.properties;
88203
+ if (!properties4 || !Object.hasOwn(properties4, "computer")) {
88204
+ return schema5;
88205
+ }
88206
+ const { computer: _computer, ...rest3 } = properties4;
88207
+ return { ...schema5, properties: rest3 };
88208
+ }
88209
+ function stripComputerFromTaskDescription(description) {
88210
+ const start = description.indexOf(COMPUTER_SECTION_HEADING);
88211
+ if (start === -1) {
88212
+ return description;
88213
+ }
88214
+ const afterHeading = start + COMPUTER_SECTION_HEADING.length;
88215
+ const next = description.indexOf(`
88216
+ ## `, afterHeading);
88217
+ const removed = next === -1 ? description.slice(0, start) : description.slice(0, start) + description.slice(next + 1);
88218
+ return removed.replace(/\n{3,}/g, `
88219
+
88220
+ `).trimEnd();
88221
+ }
88222
+ var COMPUTER_SECTION_HEADING = "## Running on Another Computer";
88223
+
88173
88224
  // src/tools/define-tool.ts
88174
88225
  function defineTool(input) {
88175
88226
  return {
@@ -89144,6 +89195,37 @@ Agent({ subagent_type: "fork", description: "Implement component B", prompt: "..
89144
89195
 
89145
89196
  Note: \`fork\` cannot be combined with \`agent_id\` or \`conversation_id\`.
89146
89197
 
89198
+ ## Running on Another Computer
89199
+
89200
+ Pass \`computer\` to run the subagent's turn on another connected computer instead of this machine. Works with any subagent type. The call fails fast if the named device is offline, ambiguous, or too old to support routing.
89201
+
89202
+ \`computer: "cloud"\` provisions a Cloud sandbox for the subagent's conversation and runs the turn there. Sandboxes are per-conversation: this is a separate machine from wherever you are running now, even if you are already in a Cloud sandbox.
89203
+
89204
+ Omit \`computer\` to run the subagent on the current machine. That is the default and the right choice for almost all tasks — the subagent shares your working directory and files. Only set \`computer\` when the task specifically needs another machine (its files, its OS, or an isolated sandbox).
89205
+
89206
+ \`\`\`typescript
89207
+ // Fork this conversation and run the work on a connected computer
89208
+ Agent({
89209
+ subagent_type: "fork",
89210
+ computer: "office-mac",
89211
+ description: "Run integration tests",
89212
+ prompt: "Run the integration suite in the checkout on this machine and report failures."
89213
+ })
89214
+
89215
+ // Deploy an existing agent into a fresh Cloud sandbox
89216
+ Agent({
89217
+ agent_id: "agent-abc123",
89218
+ computer: "cloud",
89219
+ description: "Build release artifacts",
89220
+ prompt: "Build and upload the release artifacts."
89221
+ })
89222
+ \`\`\`
89223
+
89224
+ Behavior notes:
89225
+ - The remote turn runs with the remote machine's working directory, tools, and skills. Subagent-type tool restrictions (e.g. recall's read-only toolset) travel with the turn on current servers; older servers ignore them.
89226
+ - The remote turn's final assistant message is returned as the task result. Token and step statistics are not available for remote runs.
89227
+ - The wait tracks turn liveness (new messages, run activity, device online) with an absolute one-hour ceiling rather than a fixed timeout.
89228
+
89147
89229
  ## Concurrency and Safety:
89148
89230
 
89149
89231
  - **Safe**: Multiple read-only agents (e.g. recall, history-analyzer) running in parallel
@@ -93630,7 +93712,7 @@ var LETTA_BIN_ARGS_ENV = "LETTA_CODE_BIN_ARGS_JSON", SHELL_SHIM_DIR_NAME = "lett
93630
93712
  var init_shell_env = __esm(() => {
93631
93713
  init_context();
93632
93714
  init_memory_filesystem2();
93633
- init_client2();
93715
+ init_server_url();
93634
93716
  init_paths();
93635
93717
  init_runtime_context();
93636
93718
  init_settings_manager();
@@ -114705,6 +114787,9 @@ function buildSubagentArgs(type3, config, model, userPrompt, existingAgentId, ex
114705
114787
  if (options.backendMode) {
114706
114788
  args.push("--backend", options.backendMode);
114707
114789
  }
114790
+ if (options.environment) {
114791
+ args.push("--environment", options.environment);
114792
+ }
114708
114793
  if (isDeployingExisting) {
114709
114794
  if (existingConversationId) {
114710
114795
  args.push("--conv", existingConversationId);
@@ -114765,7 +114850,7 @@ function buildSubagentArgs(type3, config, model, userPrompt, existingAgentId, ex
114765
114850
  }
114766
114851
  return args;
114767
114852
  }
114768
- async function executeSubagent(type3, config, model, userPrompt, subagentId, isRetry = false, signal, existingAgentId, existingConversationId, maxTurns, parentAgentIdOverride, transcriptPath, memoryScope, systemPromptOverride) {
114853
+ async function executeSubagent(type3, config, model, userPrompt, subagentId, isRetry = false, signal, existingAgentId, existingConversationId, maxTurns, parentAgentIdOverride, transcriptPath, memoryScope, systemPromptOverride, environment2) {
114769
114854
  const withModel = (result) => model ? { ...result, model } : result;
114770
114855
  if (signal?.aborted) {
114771
114856
  return withModel({
@@ -114792,7 +114877,8 @@ async function executeSubagent(type3, config, model, userPrompt, subagentId, isR
114792
114877
  backendMode,
114793
114878
  promptTransport: "stdin",
114794
114879
  parentAgentId,
114795
- systemPromptOverride
114880
+ systemPromptOverride,
114881
+ environment: environment2
114796
114882
  });
114797
114883
  const launcher = resolveSubagentLauncher(cliArgs);
114798
114884
  const settings3 = await settingsManager.getSettingsWithSecureTokens();
@@ -114913,12 +114999,12 @@ async function executeSubagent(type3, config, model, userPrompt, subagentId, isR
114913
114999
  agentId: parentAgentIdOverride
114914
115000
  });
114915
115001
  if (primaryModel) {
114916
- return executeSubagent(type3, config, primaryModel, userPrompt, subagentId, true, signal, undefined, undefined, maxTurns, parentAgentIdOverride, transcriptPath);
115002
+ return executeSubagent(type3, config, primaryModel, userPrompt, subagentId, true, signal, undefined, undefined, maxTurns, parentAgentIdOverride, transcriptPath, undefined, undefined, environment2);
114917
115003
  }
114918
115004
  }
114919
115005
  if (!isRetry && isSubagentStdoutLostError(stderr)) {
114920
115006
  debugWarn("subagent", `Subagent ${subagentId} lost stdout before its result envelope; retrying once`);
114921
- return executeSubagent(type3, config, model, userPrompt, subagentId, true, signal, existingAgentId, existingConversationId, maxTurns, parentAgentIdOverride, transcriptPath, memoryScope, systemPromptOverride);
115007
+ return executeSubagent(type3, config, model, userPrompt, subagentId, true, signal, existingAgentId, existingConversationId, maxTurns, parentAgentIdOverride, transcriptPath, memoryScope, systemPromptOverride, environment2);
114922
115008
  }
114923
115009
  const propagatedError = state.finalError?.trim();
114924
115010
  const fallbackError = stderr || `Subagent exited with code ${exitCode}`;
@@ -114963,7 +115049,7 @@ async function executeSubagent(type3, config, model, userPrompt, subagentId, isR
114963
115049
  debugWarn("subagent", `parseResultFromStdout failed for ${subagentId}: ${result.error}. ` + `stdout first 500 chars: ${stdout.slice(0, 500)}`);
114964
115050
  if (!isRetry && looksLikeTruncatedStreamJson(stdout)) {
114965
115051
  debugWarn("subagent", `Subagent ${subagentId} stdout ends mid-line with no result envelope; retrying once`);
114966
- return executeSubagent(type3, config, model, userPrompt, subagentId, true, signal, existingAgentId, existingConversationId, maxTurns, parentAgentIdOverride, transcriptPath, memoryScope, systemPromptOverride);
115052
+ return executeSubagent(type3, config, model, userPrompt, subagentId, true, signal, existingAgentId, existingConversationId, maxTurns, parentAgentIdOverride, transcriptPath, memoryScope, systemPromptOverride, environment2);
114967
115053
  }
114968
115054
  }
114969
115055
  return withModel(result);
@@ -115022,7 +115108,7 @@ ${SYSTEM_REMINDER_CLOSE}
115022
115108
 
115023
115109
  `;
115024
115110
  }
115025
- async function spawnSubagent(type3, prompt, userModel, subagentId, signal, existingAgentId, existingConversationId, maxTurns, forkedContext, parentAgentId, transcriptPath, parentConversationId, memoryScope, systemPromptOverride) {
115111
+ async function spawnSubagent(type3, prompt, userModel, subagentId, signal, existingAgentId, existingConversationId, maxTurns, forkedContext, parentAgentId, transcriptPath, parentConversationId, memoryScope, systemPromptOverride, environment2) {
115026
115112
  const allConfigs = await getAllSubagentConfigs();
115027
115113
  let config = allConfigs[type3];
115028
115114
  if (!config) {
@@ -115087,7 +115173,7 @@ async function spawnSubagent(type3, prompt, userModel, subagentId, signal, exist
115087
115173
  conversationId: existingConversationId
115088
115174
  });
115089
115175
  }
115090
- const result = await executeSubagent(type3, config, model, finalPrompt, subagentId, false, signal, existingAgentId, existingConversationId, maxTurns, resolvedParentAgentId, transcriptPath, memoryScope, effectiveSystemPromptOverride);
115176
+ const result = await executeSubagent(type3, config, model, finalPrompt, subagentId, false, signal, existingAgentId, existingConversationId, maxTurns, resolvedParentAgentId, transcriptPath, memoryScope, effectiveSystemPromptOverride, environment2);
115091
115177
  return result;
115092
115178
  }
115093
115179
  var NO_BASE_TOOL_SUBAGENT_TYPES;
@@ -115260,6 +115346,7 @@ function spawnBackgroundSubagentTask(args) {
115260
115346
  onComplete,
115261
115347
  transcriptPath,
115262
115348
  memoryScope,
115349
+ environment: environment2,
115263
115350
  deps
115264
115351
  } = args;
115265
115352
  const shouldEmitCompletionNotification = emitCompletionNotification ?? !silentCompletion;
@@ -115293,7 +115380,7 @@ function spawnBackgroundSubagentTask(args) {
115293
115380
  backgroundTasks.set(taskId, bgTask);
115294
115381
  writeTaskTranscriptStart(outputFile, description, subagentType);
115295
115382
  const parentAgentIdForSpawn = resolvedParentScope?.agentId;
115296
- spawnSubagentFn(subagentType, prompt, model, subagentId, abortController.signal, existingAgentId, existingConversationId, maxTurns, forkedContext, parentAgentIdForSpawn, transcriptPath, resolvedParentScope?.conversationId, memoryScope, systemPromptOverride).then(async (result) => {
115383
+ spawnSubagentFn(subagentType, prompt, model, subagentId, abortController.signal, existingAgentId, existingConversationId, maxTurns, forkedContext, parentAgentIdForSpawn, transcriptPath, resolvedParentScope?.conversationId, memoryScope, systemPromptOverride, environment2).then(async (result) => {
115297
115384
  await copyGitHubPullRequestTagsFn(result.conversationId, resolvedParentScope?.conversationId);
115298
115385
  bgTask.status = result.success ? "completed" : "failed";
115299
115386
  if (result.error) {
@@ -115489,6 +115576,17 @@ async function task(args) {
115489
115576
  if (!config) {
115490
115577
  return `Error: Invalid subagent type "${subagent_type}"`;
115491
115578
  }
115579
+ if (typeof args.computer === "string" && args.computer.trim()) {
115580
+ let environmentRouting = false;
115581
+ try {
115582
+ environmentRouting = getBackend().capabilities.environmentRouting;
115583
+ } catch {
115584
+ environmentRouting = false;
115585
+ }
115586
+ if (!environmentRouting) {
115587
+ return "Error: The computer option requires a Letta Cloud backend. This backend has no connected computers; omit the computer field to run the subagent on the current machine.";
115588
+ }
115589
+ }
115492
115590
  let effectiveAgentId = args.agent_id;
115493
115591
  let effectiveConversationId = args.conversation_id;
115494
115592
  if (config.fork) {
@@ -115525,7 +115623,8 @@ async function task(args) {
115525
115623
  existingConversationId: effectiveConversationId,
115526
115624
  maxTurns: args.max_turns,
115527
115625
  forkedContext: config.fork,
115528
- parentScope: resolvedParentScope
115626
+ parentScope: resolvedParentScope,
115627
+ environment: typeof args.computer === "string" && args.computer.trim() ? args.computer.trim() : undefined
115529
115628
  });
115530
115629
  await waitForBackgroundSubagentLink(subagentId, null, signal);
115531
115630
  const linkedAgent = getSnapshot().agents.find((a) => a.id === subagentId);
@@ -117167,6 +117266,10 @@ var init_Task2 = __esm(() => {
117167
117266
  conversation_id: {
117168
117267
  type: "string",
117169
117268
  description: "Resume from an existing conversation. Does NOT require agent_id (conversation IDs are unique and encode the agent)."
117269
+ },
117270
+ computer: {
117271
+ type: "string",
117272
+ description: `Run the subagent on another connected computer instead of this machine. Pass a computer name/connection ID, or "cloud" to provision a Cloud sandbox for the subagent's conversation. Fails fast if the device is offline or does not support routing. Omit this field to run on the current machine (the default) — only set it when the task specifically needs to run elsewhere.`
117170
117273
  }
117171
117274
  },
117172
117275
  required: ["description", "prompt", "subagent_type"],
@@ -118065,6 +118168,21 @@ ${WINDOWS_UNIFIED_EXEC_GUIDANCE}`;
118065
118168
 
118066
118169
  // src/tools/memory-tool-assets.ts
118067
118170
  async function resolveBackendSpecificToolAssets(name, description, inputSchema) {
118171
+ if (name === "Task") {
118172
+ let environmentRouting = false;
118173
+ try {
118174
+ environmentRouting = getBackend().capabilities.environmentRouting;
118175
+ } catch {
118176
+ environmentRouting = false;
118177
+ }
118178
+ if (!environmentRouting) {
118179
+ return {
118180
+ description: stripComputerFromTaskDescription(description),
118181
+ inputSchema: stripComputerFromTaskSchema(inputSchema)
118182
+ };
118183
+ }
118184
+ return { description, inputSchema };
118185
+ }
118068
118186
  let isLocalMemfs = false;
118069
118187
  try {
118070
118188
  isLocalMemfs = getBackend().capabilities.localMemfs;
@@ -125738,7 +125856,7 @@ async function applyMemfsFlags(agentId, memfsFlag, options) {
125738
125856
  };
125739
125857
  }
125740
125858
  async function isLettaCloud() {
125741
- const { getServerUrl: getServerUrl2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
125859
+ const { getServerUrl: getServerUrl2 } = await Promise.resolve().then(() => (init_server_url(), exports_server_url));
125742
125860
  const serverUrl = getServerUrl2();
125743
125861
  return serverUrl.includes("api.letta.com") || process.env.LETTA_MEMFS_LOCAL === "1" || process.env.LETTA_API_KEY === "local-desktop";
125744
125862
  }
@@ -130943,6 +131061,7 @@ var init_local_provider_errors = __esm(() => {
130943
131061
  var exports_fake_headless_backend = {};
130944
131062
  __export(exports_fake_headless_backend, {
130945
131063
  HeadlessBackend: () => HeadlessBackend,
131064
+ HEADLESS_BACKEND_CAPABILITIES: () => HEADLESS_BACKEND_CAPABILITIES,
130946
131065
  FakeHeadlessBackend: () => HeadlessBackend
130947
131066
  });
130948
131067
  function createPage(items3) {
@@ -131036,16 +131155,7 @@ function isTerminalRun(run) {
131036
131155
  }
131037
131156
 
131038
131157
  class HeadlessBackend {
131039
- capabilities = {
131040
- remoteMemfs: false,
131041
- serverSideToolManagement: false,
131042
- serverSecrets: false,
131043
- agentFileImportExport: false,
131044
- promptRecompile: false,
131045
- byokProviderRefresh: false,
131046
- localModelCatalog: true,
131047
- localMemfs: false
131048
- };
131158
+ capabilities = HEADLESS_BACKEND_CAPABILITIES;
131049
131159
  store;
131050
131160
  executor;
131051
131161
  runs = new Map;
@@ -131421,13 +131531,24 @@ class HeadlessBackend {
131421
131531
  };
131422
131532
  }
131423
131533
  }
131424
- var FAKE_HEADLESS_MODEL = "dev/fake-headless";
131534
+ var FAKE_HEADLESS_MODEL = "dev/fake-headless", HEADLESS_BACKEND_CAPABILITIES;
131425
131535
  var init_fake_headless_backend = __esm(() => {
131426
131536
  init_model_handles();
131427
131537
  init_local_store();
131428
131538
  init_local_stream_chunks();
131429
131539
  init_constants2();
131430
131540
  init_local_provider_errors();
131541
+ HEADLESS_BACKEND_CAPABILITIES = {
131542
+ remoteMemfs: false,
131543
+ serverSideToolManagement: false,
131544
+ serverSecrets: false,
131545
+ agentFileImportExport: false,
131546
+ promptRecompile: false,
131547
+ byokProviderRefresh: false,
131548
+ localModelCatalog: true,
131549
+ localMemfs: false,
131550
+ environmentRouting: false
131551
+ };
131431
131552
  });
131432
131553
 
131433
131554
  // src/backend/dev/headless-backend.ts
@@ -135080,13 +135201,8 @@ var init_local_backend = __esm(() => {
135080
135201
  init_system_prompt_compilation();
135081
135202
  LocalBackend = class LocalBackend extends HeadlessBackend {
135082
135203
  capabilities = {
135083
- remoteMemfs: false,
135084
- serverSideToolManagement: false,
135085
- serverSecrets: false,
135086
- agentFileImportExport: false,
135204
+ ...HEADLESS_BACKEND_CAPABILITIES,
135087
135205
  promptRecompile: true,
135088
- byokProviderRefresh: false,
135089
- localModelCatalog: true,
135090
135206
  localMemfs: true
135091
135207
  };
135092
135208
  memoryDir;
@@ -135513,16 +135629,19 @@ function toApiConversationMessageListBody(body) {
135513
135629
  }
135514
135630
 
135515
135631
  class APIBackend {
135516
- capabilities = {
135517
- remoteMemfs: true,
135518
- serverSideToolManagement: true,
135519
- serverSecrets: true,
135520
- agentFileImportExport: true,
135521
- promptRecompile: true,
135522
- byokProviderRefresh: true,
135523
- localModelCatalog: false,
135524
- localMemfs: false
135525
- };
135632
+ get capabilities() {
135633
+ return {
135634
+ remoteMemfs: true,
135635
+ serverSideToolManagement: true,
135636
+ serverSecrets: true,
135637
+ agentFileImportExport: true,
135638
+ promptRecompile: true,
135639
+ byokProviderRefresh: true,
135640
+ localModelCatalog: false,
135641
+ localMemfs: false,
135642
+ environmentRouting: isCloudServerUrl()
135643
+ };
135644
+ }
135526
135645
  getApiClientOverride;
135527
135646
  forkConversationOverride;
135528
135647
  constructor(deps = {}) {
@@ -135744,6 +135863,7 @@ function __testSetBackend(nextBackend) {
135744
135863
  }
135745
135864
  var DEFAULT_CONVERSATION_MESSAGE_ORDER = "desc", backend = null;
135746
135865
  var init_backend = __esm(() => {
135866
+ init_server_url();
135747
135867
  init_backend_mode();
135748
135868
  init_local_backend();
135749
135869
  init_paths();
@@ -394179,6 +394299,29 @@ function buildTeleportContinuationMessages(params) {
394179
394299
  }
394180
394300
  ];
394181
394301
  }
394302
+ function escapeSystemReminderText(value) {
394303
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
394304
+ }
394305
+ function buildTeleportFailureMessages(params) {
394306
+ const messages = [];
394307
+ if (params.approvals && params.approvals.length > 0) {
394308
+ messages.push({
394309
+ type: "approval",
394310
+ approvals: params.approvals,
394311
+ otid: params.teleportId
394312
+ });
394313
+ }
394314
+ messages.push({
394315
+ role: "system",
394316
+ content: `<system-reminder>Teleportation failed.
394317
+
394318
+ Error: ${escapeSystemReminderText(params.error)}
394319
+
394320
+ Continue the existing task from this environment now.</system-reminder>`,
394321
+ otid: `${params.teleportId}:failed`
394322
+ });
394323
+ return messages;
394324
+ }
394182
394325
  function getPendingTeleports(runtime) {
394183
394326
  runtime.pendingTeleports ??= new Map;
394184
394327
  return runtime.pendingTeleports;
@@ -394357,11 +394500,43 @@ function takeFailedTeleport(params) {
394357
394500
  params.listener.pendingTeleports?.delete(params.teleportId);
394358
394501
  return pending;
394359
394502
  }
394503
+ function handleTeleportFailure(params) {
394504
+ const pending = takeFailedTeleport({
394505
+ listener: params.listener,
394506
+ teleportId: params.command.teleport_id,
394507
+ agentId: params.command.runtime.agent_id,
394508
+ conversationId: params.command.runtime.conversation_id
394509
+ });
394510
+ if (!pending)
394511
+ return;
394512
+ const runtime = params.getOrCreateScopedRuntime(params.listener, pending.agentId, pending.conversationId);
394513
+ emitLoopErrorNotice(params.socket, runtime, {
394514
+ message: `Teleport failed: ${params.command.error}`,
394515
+ stopReason: "error",
394516
+ isTerminal: false,
394517
+ agentId: pending.agentId,
394518
+ conversationId: pending.conversationId
394519
+ });
394520
+ params.runDetachedListenerTask("teleport_failed", async () => {
394521
+ await params.processIncomingMessage({
394522
+ type: "message",
394523
+ connectionId: pending.connectionId,
394524
+ agentId: pending.agentId,
394525
+ conversationId: pending.conversationId,
394526
+ messages: buildTeleportFailureMessages({
394527
+ teleportId: params.command.teleport_id,
394528
+ error: params.command.error,
394529
+ approvals: pending.continuation?.approvals
394530
+ })
394531
+ }, params.socket, runtime, params.onStatusChange, pending.connectionId);
394532
+ });
394533
+ }
394360
394534
  var TELEPORT_RECOVERY_TTL_MS;
394361
394535
  var init_teleport = __esm(() => {
394362
394536
  init_connection();
394363
394537
  init_permission_mode();
394364
394538
  init_protocol_outbound();
394539
+ init_recoverable_notices();
394365
394540
  init_runtime();
394366
394541
  init_transport();
394367
394542
  TELEPORT_RECOVERY_TTL_MS = 5 * 60000;
@@ -409763,31 +409938,15 @@ function createListenerMessageHandler(params) {
409763
409938
  return;
409764
409939
  }
409765
409940
  if (parsed.type === "teleport_failed") {
409766
- const pending = takeFailedTeleport({
409941
+ handleTeleportFailure({
409767
409942
  listener: runtime,
409768
- teleportId: parsed.teleport_id,
409769
- agentId: parsed.runtime.agent_id,
409770
- conversationId: parsed.runtime.conversation_id
409943
+ command: parsed,
409944
+ socket,
409945
+ onStatusChange: opts.onStatusChange,
409946
+ getOrCreateScopedRuntime: getOrCreateScopedRuntime2,
409947
+ runDetachedListenerTask,
409948
+ processIncomingMessage
409771
409949
  });
409772
- const approvals = pending?.continuation?.approvals;
409773
- if (pending && approvals && approvals.length > 0) {
409774
- const scopedRuntime = getOrCreateScopedRuntime2(runtime, pending.agentId, pending.conversationId);
409775
- runDetachedListenerTask("teleport_failed", async () => {
409776
- await processIncomingMessage({
409777
- type: "message",
409778
- connectionId: pending.connectionId,
409779
- agentId: pending.agentId,
409780
- conversationId: pending.conversationId,
409781
- messages: [
409782
- {
409783
- type: "approval",
409784
- approvals,
409785
- otid: parsed.teleport_id
409786
- }
409787
- ]
409788
- }, socket, scopedRuntime, opts.onStatusChange, pending.connectionId);
409789
- });
409790
- }
409791
409950
  return;
409792
409951
  }
409793
409952
  if (parsed.type === "external_tool_call_response") {
@@ -432006,7 +432165,7 @@ var init_mcp_client = __esm(() => {
432006
432165
  init_streamableHttp();
432007
432166
  DEFAULT_CLIENT_INFO = {
432008
432167
  name: "letta-code",
432009
- version: "0.31.8"
432168
+ version: "0.31.10"
432010
432169
  };
432011
432170
  });
432012
432171
 
@@ -439183,7 +439342,7 @@ Notes:
439183
439342
  - Operates on the current agent/conversation from LETTA_AGENT_ID /
439184
439343
  LETTA_CONVERSATION_ID (or AGENT_ID / CONVERSATION_ID), falling back to the
439185
439344
  last active session.
439186
- - Requires a Letta Cloud agent and a non-virtual conversation.
439345
+ - Requires a Letta Cloud agent and an active conversation.
439187
439346
  - list: prints accessible online remote environments as JSON.
439188
439347
  - cloud: teleports to the agent's Cloud sandbox.
439189
439348
  - local: teleports to the one online Desktop environment. Desktop Remote
@@ -439219,7 +439378,7 @@ function resolveTeleportSession(env4, fallback) {
439219
439378
  if (isLocalAgentId(session.agentId)) {
439220
439379
  throw new Error("Teleport requires a Letta Cloud agent");
439221
439380
  }
439222
- if (!session.conversationId || session.conversationId === "default" || session.conversationId === "new") {
439381
+ if (!session.conversationId || session.conversationId === "new") {
439223
439382
  throw new Error("Teleport requires an active conversation");
439224
439383
  }
439225
439384
  return session;
@@ -445203,8 +445362,8 @@ async function startDockerVersionCheck() {
445203
445362
  }
445204
445363
  var MINIMUM_DOCKER_VERSION = "0.16.6";
445205
445364
  var init_startup_docker_check = __esm(() => {
445206
- init_client2();
445207
445365
  init_health();
445366
+ init_server_url();
445208
445367
  });
445209
445368
 
445210
445369
  // src/agent/bootstrap-tools.ts
@@ -445579,7 +445738,43 @@ var init_local_backend_mod_events = __esm(() => {
445579
445738
  init_local_backend();
445580
445739
  });
445581
445740
 
445741
+ // src/backend/api/agents.ts
445742
+ async function getAgentContextOverview(agentId, options) {
445743
+ return apiRequest("GET", `/v1/agents/${agentId}/context`, undefined, {
445744
+ signal: options?.signal
445745
+ });
445746
+ }
445747
+ async function createMinimalAgent(apiKey, name) {
445748
+ return apiRequest("POST", "/v1/agents", { name }, {
445749
+ baseUrl: "https://api.letta.com",
445750
+ apiKey
445751
+ });
445752
+ }
445753
+ async function getAgentRuntimeStatus(agentId, conversationIds) {
445754
+ return apiRequest("GET", `/v1/agents/${encodeURIComponent(agentId)}/runtime-status`, undefined, { query: { conversation_ids: conversationIds.join(",") } });
445755
+ }
445756
+ var init_agents7 = __esm(() => {
445757
+ init_request();
445758
+ });
445759
+
445582
445760
  // src/headless-environment-response.ts
445761
+ import { randomUUID as randomUUID35 } from "node:crypto";
445762
+ function buildEnvironmentCreateMessageBody(params) {
445763
+ const clientToolAllowlist = toolFilter.getEnabledTools();
445764
+ return {
445765
+ agentId: params.agentId,
445766
+ conversationId: params.conversationId,
445767
+ ...clientToolAllowlist !== null ? { client_tool_allowlist: clientToolAllowlist } : {},
445768
+ messages: [
445769
+ {
445770
+ role: "user",
445771
+ content: params.content,
445772
+ client_message_id: randomUUID35(),
445773
+ otid: params.otid
445774
+ }
445775
+ ]
445776
+ };
445777
+ }
445583
445778
  function pageItems5(page) {
445584
445779
  if (Array.isArray(page))
445585
445780
  return page;
@@ -445628,12 +445823,42 @@ function messageSequenceId(message) {
445628
445823
  const sequenceId = message.seq_id;
445629
445824
  return typeof sequenceId === "number" ? sequenceId : null;
445630
445825
  }
445826
+ function resolveEnvironmentMaxWaitMs() {
445827
+ const raw2 = process.env.LETTA_ENVIRONMENT_TIMEOUT_MS;
445828
+ if (raw2) {
445829
+ const parsed = Number(raw2);
445830
+ if (Number.isFinite(parsed) && parsed > 0)
445831
+ return parsed;
445832
+ }
445833
+ return DEFAULT_MAX_WAIT_MS;
445834
+ }
445835
+ function isTerminalRunStatus(status) {
445836
+ return status === "completed" || status === "failed" || status === "cancelled";
445837
+ }
445838
+ function isRuntimeTurnOver(status) {
445839
+ return status.state === "IDLE" || status.loop_state?.status === "WAITING_ON_INPUT";
445840
+ }
445631
445841
  async function waitForEnvironmentAssistantMessage(params) {
445632
- const timeoutMs = params.timeoutMs ?? 10 * 60000;
445842
+ const now2 = params.deps?.now ?? Date.now;
445843
+ const sleep10 = params.deps?.sleep ?? ((ms) => new Promise((resolve38) => setTimeout(resolve38, ms)));
445844
+ const fetchEnvironment = params.deps?.getEnvironmentConnection ?? getEnvironmentConnection;
445845
+ const fetchRuntimeStatus = params.deps?.getAgentRuntimeStatus ?? getAgentRuntimeStatus;
445846
+ const maxWaitMs = params.maxWaitMs ?? resolveEnvironmentMaxWaitMs();
445847
+ const inactivityTimeoutMs = params.inactivityTimeoutMs ?? DEFAULT_INACTIVITY_TIMEOUT_MS;
445633
445848
  const pollIntervalMs = params.pollIntervalMs ?? 1000;
445634
- const deadline = Date.now() + timeoutMs;
445849
+ const onlineCheckIntervalMs = params.onlineCheckIntervalMs ?? DEFAULT_ONLINE_CHECK_INTERVAL_MS;
445850
+ const runStatusIntervalMs = params.runStatusIntervalMs ?? DEFAULT_RUN_STATUS_INTERVAL_MS;
445851
+ const startedAt = now2();
445852
+ let lastProgressAt = startedAt;
445853
+ let lastOnlineCheckAt = startedAt;
445854
+ let lastRunStatusCheckAt = 0;
445855
+ let lastRuntimeStatusCheckAt = 0;
445856
+ let mode = "unknown";
445857
+ let runtimeTurnOverAt = null;
445858
+ let highestSequenceId = null;
445859
+ let completedWithoutTextAt = null;
445635
445860
  let inputSequenceId = null;
445636
- while (Date.now() < deadline) {
445861
+ while (true) {
445637
445862
  const page = params.conversationId === "default" ? await params.backend.listAgentMessages(params.agentId, {
445638
445863
  conversation_id: "default",
445639
445864
  limit: 50,
@@ -445643,10 +445868,19 @@ async function waitForEnvironmentAssistantMessage(params) {
445643
445868
  order: "desc"
445644
445869
  });
445645
445870
  const messages = pageItems5(page);
445871
+ for (const message of messages) {
445872
+ const sequenceId = messageSequenceId(message);
445873
+ if (sequenceId !== null && (highestSequenceId === null || sequenceId > highestSequenceId)) {
445874
+ highestSequenceId = sequenceId;
445875
+ lastProgressAt = now2();
445876
+ }
445877
+ }
445646
445878
  if (inputSequenceId === null) {
445647
445879
  const inputMessage = messages.find((message) => isUserMessage(message) && message.otid === params.otid);
445648
445880
  inputSequenceId = inputMessage ? messageSequenceId(inputMessage) : null;
445649
445881
  }
445882
+ let assistant;
445883
+ let newestRunId = null;
445650
445884
  if (inputSequenceId !== null) {
445651
445885
  const anchorSequenceId = inputSequenceId;
445652
445886
  const newerMessages = messages.filter((message) => {
@@ -445662,25 +445896,104 @@ async function waitForEnvironmentAssistantMessage(params) {
445662
445896
  return closest;
445663
445897
  return closest === null || sequenceId < closest ? sequenceId : closest;
445664
445898
  }, null);
445665
- const assistant = newerMessages.filter((message) => {
445899
+ const turnMessages = newerMessages.filter((message) => {
445666
445900
  const sequenceId = messageSequenceId(message);
445667
- return isAssistantMessage2(message) && sequenceId !== null && (nextUserSequenceId === null || sequenceId < nextUserSequenceId);
445668
- }).sort((a2, b3) => (messageSequenceId(b3) ?? 0) - (messageSequenceId(a2) ?? 0))[0];
445669
- const runId = messageRunId(assistant);
445670
- if (runId) {
445671
- const run = await params.backend.retrieveRun(runId);
445672
- if ((run.status === "completed" || run.status === "failed" || run.status === "cancelled") && run.stop_reason !== "requires_approval") {
445901
+ return sequenceId !== null && (nextUserSequenceId === null || sequenceId < nextUserSequenceId);
445902
+ });
445903
+ assistant = turnMessages.filter((message) => isAssistantMessage2(message)).sort((a2, b3) => (messageSequenceId(b3) ?? 0) - (messageSequenceId(a2) ?? 0))[0];
445904
+ newestRunId = messageRunId(assistant) ?? turnMessages.sort((a2, b3) => (messageSequenceId(b3) ?? 0) - (messageSequenceId(a2) ?? 0)).map((message) => messageRunId(message)).find((id2) => id2 !== null) ?? null;
445905
+ }
445906
+ if (mode !== "runs") {
445907
+ const shouldCheckRuntimeStatus = assistant !== undefined || lastRuntimeStatusCheckAt === 0 || now2() - lastRuntimeStatusCheckAt >= runStatusIntervalMs;
445908
+ if (shouldCheckRuntimeStatus) {
445909
+ lastRuntimeStatusCheckAt = now2();
445910
+ let snapshot = null;
445911
+ try {
445912
+ snapshot = await fetchRuntimeStatus(params.agentId, [
445913
+ params.conversationId
445914
+ ]);
445915
+ } catch (error5) {
445916
+ if (error5 instanceof ApiRequestError && error5.status === 404) {
445917
+ mode = "runs";
445918
+ }
445919
+ }
445920
+ if (snapshot) {
445921
+ mode = "runtime-status";
445922
+ const status = snapshot.statuses.find((entry) => entry.conversation_id === params.conversationId) ?? (snapshot.statuses.length === 1 ? snapshot.statuses[0] : null) ?? null;
445923
+ if (status && !isRuntimeTurnOver(status)) {
445924
+ lastProgressAt = now2();
445925
+ runtimeTurnOverAt = null;
445926
+ } else if (status && inputSequenceId !== null) {
445927
+ const text2 = assistant ? extractMessageText(assistant).trim() : "";
445928
+ if (text2.length > 0) {
445929
+ let stopReason = null;
445930
+ if (newestRunId) {
445931
+ try {
445932
+ const run = await params.backend.retrieveRun(newestRunId);
445933
+ stopReason = run.stop_reason ?? null;
445934
+ } catch {}
445935
+ }
445936
+ return { text: text2, stopReason };
445937
+ }
445938
+ runtimeTurnOverAt ??= now2();
445939
+ if (now2() - runtimeTurnOverAt >= COMPLETED_WITHOUT_TEXT_GRACE_MS) {
445940
+ throw new Error("Environment turn ended without an assistant reply " + `(runtime state ${status.state})`);
445941
+ }
445942
+ }
445943
+ }
445944
+ }
445945
+ }
445946
+ if (mode !== "runtime-status" && inputSequenceId !== null) {
445947
+ const shouldCheckRun = newestRunId !== null && (assistant !== undefined || now2() - lastRunStatusCheckAt >= runStatusIntervalMs);
445948
+ if (newestRunId && shouldCheckRun) {
445949
+ lastRunStatusCheckAt = now2();
445950
+ const run = await params.backend.retrieveRun(newestRunId);
445951
+ if (!isTerminalRunStatus(run.status)) {
445952
+ lastProgressAt = now2();
445953
+ } else if (run.stop_reason !== "requires_approval") {
445673
445954
  const text2 = assistant ? extractMessageText(assistant).trim() : "";
445674
445955
  if (text2.length > 0) {
445675
445956
  return { text: text2, stopReason: run.stop_reason ?? null };
445676
445957
  }
445958
+ if (run.status === "failed" || run.status === "cancelled") {
445959
+ throw new Error(`Environment turn run ${newestRunId} ${run.status} without an assistant reply` + (run.stop_reason ? ` (stop reason: ${run.stop_reason})` : ""));
445960
+ }
445961
+ completedWithoutTextAt ??= now2();
445962
+ if (now2() - completedWithoutTextAt >= COMPLETED_WITHOUT_TEXT_GRACE_MS) {
445963
+ throw new Error(`Environment turn run ${newestRunId} completed without an assistant reply`);
445964
+ }
445677
445965
  }
445678
445966
  }
445679
445967
  }
445680
- await new Promise((resolve38) => setTimeout(resolve38, pollIntervalMs));
445968
+ if (params.deviceId && now2() - lastOnlineCheckAt >= onlineCheckIntervalMs) {
445969
+ lastOnlineCheckAt = now2();
445970
+ let offline = false;
445971
+ try {
445972
+ const connection = await fetchEnvironment(params.deviceId);
445973
+ offline = !isEnvironmentOnline(connection);
445974
+ } catch {}
445975
+ if (offline) {
445976
+ throw new Error(`Environment device ${params.deviceId} went offline before the turn completed`);
445977
+ }
445978
+ }
445979
+ if (now2() - lastProgressAt >= inactivityTimeoutMs) {
445980
+ throw new Error(`No activity from the environment turn for ${inactivityTimeoutMs}ms (no new messages and no running run); giving up`);
445981
+ }
445982
+ if (now2() - startedAt >= maxWaitMs) {
445983
+ throw new Error(`Environment turn did not complete within ${maxWaitMs}ms (set LETTA_ENVIRONMENT_TIMEOUT_MS to raise the ceiling)`);
445984
+ }
445985
+ await sleep10(pollIntervalMs);
445681
445986
  }
445682
- throw new Error("Timed out waiting for environment turn completion");
445683
445987
  }
445988
+ var DEFAULT_MAX_WAIT_MS, DEFAULT_INACTIVITY_TIMEOUT_MS, DEFAULT_ONLINE_CHECK_INTERVAL_MS = 30000, DEFAULT_RUN_STATUS_INTERVAL_MS = 1e4, COMPLETED_WITHOUT_TEXT_GRACE_MS = 15000;
445989
+ var init_headless_environment_response = __esm(() => {
445990
+ init_agents7();
445991
+ init_environments2();
445992
+ init_request();
445993
+ init_filter();
445994
+ DEFAULT_MAX_WAIT_MS = 60 * 60000;
445995
+ DEFAULT_INACTIVITY_TIMEOUT_MS = 10 * 60000;
445996
+ });
445684
445997
 
445685
445998
  // src/agent/ephemeral-conversation.ts
445686
445999
  async function buildEphemeralConversationCreateBody(options) {
@@ -446683,7 +446996,7 @@ async function ensureDefaultAgents(backend3, options) {
446683
446996
  }
446684
446997
  var MEMO_TAG = "default:memo", TUTOR_TAG = "default:tutorial", MEMO_PERSONA, MEMO_HUMAN, MEMO_DESCRIPTION = "The default Letta Code agent with persistent memory", DEFAULT_AGENT_CONFIGS;
446685
446998
  var init_defaults = __esm(() => {
446686
- init_client2();
446999
+ init_server_url();
446687
447000
  init_settings_manager();
446688
447001
  init_create5();
446689
447002
  init_memory();
@@ -446712,7 +447025,7 @@ __export(exports_headless, {
446712
447025
  decideInterruptAction: () => decideInterruptAction,
446713
447026
  __headlessTestUtils: () => __headlessTestUtils
446714
447027
  });
446715
- import { randomUUID as randomUUID35 } from "node:crypto";
447028
+ import { randomUUID as randomUUID36 } from "node:crypto";
446716
447029
  function trackHeadlessBoundaryError(errorType, error5, context3) {
446717
447030
  trackBoundaryError({
446718
447031
  errorType,
@@ -446734,7 +447047,7 @@ async function reportStartupErrorAndExit(errorType, error5, context3, outputForm
446734
447047
  message,
446735
447048
  stop_reason: "error",
446736
447049
  session_id: "startup",
446737
- uuid: `startup-error-${randomUUID35()}`
447050
+ uuid: `startup-error-${randomUUID36()}`
446738
447051
  };
446739
447052
  await writeWireMessageAsync(errorMsg);
446740
447053
  } else {
@@ -446833,7 +447146,7 @@ async function emitHeadlessTurnStartCancellationOutput(options) {
446833
447146
  message: options.reason,
446834
447147
  stop_reason: "cancelled",
446835
447148
  session_id: options.sessionId,
446836
- uuid: `error-turn-start-cancel-${randomUUID35()}`
447149
+ uuid: `error-turn-start-cancel-${randomUUID36()}`
446837
447150
  };
446838
447151
  await writeWireMessageAsync(errorMsg);
446839
447152
  const resultMsg = {
@@ -446848,7 +447161,7 @@ async function emitHeadlessTurnStartCancellationOutput(options) {
446848
447161
  conversation_id: options.conversationId,
446849
447162
  run_ids: [],
446850
447163
  usage: null,
446851
- uuid: `result-turn-start-cancel-${randomUUID35()}`,
447164
+ uuid: `result-turn-start-cancel-${randomUUID36()}`,
446852
447165
  stop_reason: "cancelled"
446853
447166
  };
446854
447167
  await writeWireMessageAsync(resultMsg);
@@ -446877,7 +447190,7 @@ function writeBidirectionalTurnStartCancellation(options) {
446877
447190
  message: options.reason,
446878
447191
  stop_reason: "cancelled",
446879
447192
  session_id: options.sessionId,
446880
- uuid: `error-turn-start-cancel-${randomUUID35()}`
447193
+ uuid: `error-turn-start-cancel-${randomUUID36()}`
446881
447194
  };
446882
447195
  writeWireMessage(errorMsg);
446883
447196
  const resultMsg = {
@@ -446892,7 +447205,7 @@ function writeBidirectionalTurnStartCancellation(options) {
446892
447205
  conversation_id: options.conversationId,
446893
447206
  run_ids: [],
446894
447207
  usage: null,
446895
- uuid: `result-turn-start-cancel-${randomUUID35()}`,
447208
+ uuid: `result-turn-start-cancel-${randomUUID36()}`,
446896
447209
  stop_reason: "cancelled"
446897
447210
  };
446898
447211
  writeWireMessage(resultMsg);
@@ -447771,7 +448084,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
447771
448084
  const approvalInput = {
447772
448085
  type: "approval",
447773
448086
  approvals: denialResults,
447774
- otid: randomUUID35()
448087
+ otid: randomUUID36()
447775
448088
  };
447776
448089
  const approvalMessages = [approvalInput];
447777
448090
  {
@@ -447784,7 +448097,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
447784
448097
  type: "text",
447785
448098
  text: sc.content
447786
448099
  })),
447787
- otid: randomUUID35()
448100
+ otid: randomUUID36()
447788
448101
  });
447789
448102
  }
447790
448103
  }
@@ -447817,7 +448130,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
447817
448130
  message: `Failed to resolve pending approvals on resume: ${approvalError instanceof Error ? approvalError.message : String(approvalError)}`,
447818
448131
  stop_reason: "error",
447819
448132
  session_id: sessionId,
447820
- uuid: `error-pre-loop-approval-${randomUUID35()}`
448133
+ uuid: `error-pre-loop-approval-${randomUUID36()}`
447821
448134
  };
447822
448135
  writeWireMessage(errorMsg);
447823
448136
  } else {
@@ -447956,26 +448269,20 @@ ${loadedContents.join(`
447956
448269
  }
447957
448270
  await exitHeadless(1, "headless_environment_unsupported");
447958
448271
  }
447959
- const otid = randomUUID35();
447960
- await sendEnvironmentMessage(connectionId, {
448272
+ const otid = randomUUID36();
448273
+ await sendEnvironmentMessage(connectionId, buildEnvironmentCreateMessageBody({
447961
448274
  agentId: agent.id,
447962
448275
  conversationId,
447963
- messages: [
447964
- {
447965
- role: "user",
447966
- content: contentParts,
447967
- client_message_id: randomUUID35(),
447968
- otid
447969
- }
447970
- ]
447971
- });
448276
+ content: contentParts,
448277
+ otid
448278
+ }));
447972
448279
  const environmentResult = await waitForEnvironmentAssistantMessage({
447973
448280
  backend: backend3,
447974
448281
  agentId: agent.id,
447975
448282
  conversationId,
447976
- otid
448283
+ otid,
448284
+ deviceId: environment2.deviceId
447977
448285
  });
447978
- const resultText2 = environmentResult.text;
447979
448286
  const stats2 = sessionStats.getSnapshot();
447980
448287
  if (outputFormat === "json") {
447981
448288
  await writeFinalHeadlessStdout(`${JSON.stringify({
@@ -447985,7 +448292,7 @@ ${loadedContents.join(`
447985
448292
  duration_ms: Math.round(stats2.totalWallMs),
447986
448293
  duration_api_ms: Math.round(stats2.totalApiMs),
447987
448294
  num_turns: 1,
447988
- result: resultText2,
448295
+ result: environmentResult.text,
447989
448296
  agent_id: publicAgentId,
447990
448297
  conversation_id: conversationId,
447991
448298
  environment: responseEnvironment,
@@ -448001,7 +448308,7 @@ ${loadedContents.join(`
448001
448308
  duration_ms: Math.round(stats2.totalWallMs),
448002
448309
  duration_api_ms: Math.round(stats2.totalApiMs),
448003
448310
  num_turns: 1,
448004
- result: resultText2,
448311
+ result: environmentResult.text,
448005
448312
  agent_id: publicAgentId,
448006
448313
  conversation_id: conversationId,
448007
448314
  environment: responseEnvironment,
@@ -448012,7 +448319,7 @@ ${loadedContents.join(`
448012
448319
  };
448013
448320
  writeWireMessage(resultEvent);
448014
448321
  } else {
448015
- await writeFinalHeadlessStdout(`${resultText2}
448322
+ await writeFinalHeadlessStdout(`${environmentResult.text}
448016
448323
  `);
448017
448324
  }
448018
448325
  await exitHeadless(0, "headless_environment_message_complete");
@@ -448021,7 +448328,7 @@ ${loadedContents.join(`
448021
448328
  {
448022
448329
  role: "user",
448023
448330
  content: contentParts,
448024
- otid: randomUUID35()
448331
+ otid: randomUUID36()
448025
448332
  }
448026
448333
  ];
448027
448334
  const recoveredApprovalResults = queuedRecoveredApprovalResults ?? [];
@@ -448030,7 +448337,7 @@ ${loadedContents.join(`
448030
448337
  {
448031
448338
  type: "approval",
448032
448339
  approvals: recoveredApprovalResults,
448033
- otid: randomUUID35()
448340
+ otid: randomUUID36()
448034
448341
  },
448035
448342
  ...currentInput
448036
448343
  ];
@@ -448076,7 +448383,7 @@ ${loadedContents.join(`
448076
448383
  message: `Maximum turns limit reached (${buffers.usage.stepCount}/${maxTurns} steps)`,
448077
448384
  stop_reason: "max_steps",
448078
448385
  session_id: sessionId,
448079
- uuid: `error-max-turns-${randomUUID35()}`
448386
+ uuid: `error-max-turns-${randomUUID36()}`
448080
448387
  };
448081
448388
  await writeWireMessageAsync(errorMsg);
448082
448389
  } else {
@@ -448093,7 +448400,7 @@ ${loadedContents.join(`
448093
448400
  message: "Interrupted by SIGINT",
448094
448401
  stop_reason: "cancelled",
448095
448402
  session_id: sessionId,
448096
- uuid: `error-interrupted-${randomUUID35()}`
448403
+ uuid: `error-interrupted-${randomUUID36()}`
448097
448404
  };
448098
448405
  await writeWireMessageAsync(errorMsg);
448099
448406
  } else {
@@ -448122,7 +448429,7 @@ ${loadedContents.join(`
448122
448429
  type: "text",
448123
448430
  text: sc.content
448124
448431
  })),
448125
- otid: randomUUID35()
448432
+ otid: randomUUID36()
448126
448433
  }
448127
448434
  ];
448128
448435
  }
@@ -448167,7 +448474,7 @@ ${loadedContents.join(`
448167
448474
  recovery_type: "approval_pending",
448168
448475
  message: "Detected pending approval conflict on send; resolving before retry",
448169
448476
  session_id: sessionId,
448170
- uuid: `recovery-pre-stream-${randomUUID35()}`
448477
+ uuid: `recovery-pre-stream-${randomUUID36()}`
448171
448478
  };
448172
448479
  writeWireMessage(recoveryMsg);
448173
448480
  } else {
@@ -448200,7 +448507,7 @@ ${loadedContents.join(`
448200
448507
  max_attempts: CONVERSATION_BUSY_MAX_RETRIES,
448201
448508
  delay_ms: retryDelayMs,
448202
448509
  session_id: sessionId,
448203
- uuid: `retry-conversation-busy-${randomUUID35()}`
448510
+ uuid: `retry-conversation-busy-${randomUUID36()}`
448204
448511
  };
448205
448512
  writeWireMessage(retryMsg);
448206
448513
  } else {
@@ -448228,7 +448535,7 @@ ${loadedContents.join(`
448228
448535
  max_attempts: LLM_API_ERROR_MAX_RETRIES2,
448229
448536
  delay_ms: delayMs,
448230
448537
  session_id: sessionId,
448231
- uuid: `retry-pre-stream-${randomUUID35()}`
448538
+ uuid: `retry-pre-stream-${randomUUID36()}`
448232
448539
  };
448233
448540
  writeWireMessage(retryMsg);
448234
448541
  } else {
@@ -448254,7 +448561,7 @@ ${loadedContents.join(`
448254
448561
  stop_reason: "error",
448255
448562
  run_id: errorInfo.run_id,
448256
448563
  session_id: sessionId,
448257
- uuid: randomUUID35(),
448564
+ uuid: randomUUID36(),
448258
448565
  ...errorInfo.error_type && errorInfo.run_id && {
448259
448566
  api_error: {
448260
448567
  message_type: "error_message",
@@ -448276,7 +448583,7 @@ ${loadedContents.join(`
448276
448583
  message: "Detected pending approval conflict; auto-denying stale approval and retrying",
448277
448584
  run_id: recoveryRunId ?? undefined,
448278
448585
  session_id: sessionId,
448279
- uuid: `recovery-${recoveryRunId || randomUUID35()}`
448586
+ uuid: `recovery-${recoveryRunId || randomUUID36()}`
448280
448587
  };
448281
448588
  writeWireMessage(recoveryMsg);
448282
448589
  approvalPendingRecovery = true;
@@ -448294,7 +448601,7 @@ ${loadedContents.join(`
448294
448601
  type: "stream_event",
448295
448602
  event: chunk2,
448296
448603
  session_id: sessionId,
448297
- uuid: uuid3 || randomUUID35()
448604
+ uuid: uuid3 || randomUUID36()
448298
448605
  };
448299
448606
  writeWireMessage(streamEvent);
448300
448607
  } else {
@@ -448302,7 +448609,7 @@ ${loadedContents.join(`
448302
448609
  type: "message",
448303
448610
  ...chunk2,
448304
448611
  session_id: sessionId,
448305
- uuid: uuid3 || randomUUID35()
448612
+ uuid: uuid3 || randomUUID36()
448306
448613
  };
448307
448614
  writeWireMessage(msg);
448308
448615
  }
@@ -448346,7 +448653,7 @@ ${loadedContents.join(`
448346
448653
  {
448347
448654
  role: "user",
448348
448655
  content: continueMessage,
448349
- otid: randomUUID35()
448656
+ otid: randomUUID36()
448350
448657
  }
448351
448658
  ];
448352
448659
  const continueTurnStartEmission = await emitHeadlessTurnStart({
@@ -448418,7 +448725,7 @@ ${loadedContents.join(`
448418
448725
  const approvalInputWithOtid = {
448419
448726
  type: "approval",
448420
448727
  approvals: executedResults,
448421
- otid: randomUUID35()
448728
+ otid: randomUUID36()
448422
448729
  };
448423
448730
  currentInput = [approvalInputWithOtid];
448424
448731
  continue;
@@ -448451,7 +448758,7 @@ ${loadedContents.join(`
448451
448758
  delay_ms: 0,
448452
448759
  run_id: lastRunId ?? undefined,
448453
448760
  session_id: sessionId,
448454
- uuid: `retry-${lastRunId || randomUUID35()}`
448761
+ uuid: `retry-${lastRunId || randomUUID36()}`
448455
448762
  };
448456
448763
  writeWireMessage(retryMsg);
448457
448764
  } else {
@@ -448479,7 +448786,7 @@ ${loadedContents.join(`
448479
448786
  delay_ms: delayMs,
448480
448787
  run_id: lastRunId ?? undefined,
448481
448788
  session_id: sessionId,
448482
- uuid: `retry-${lastRunId || randomUUID35()}`
448789
+ uuid: `retry-${lastRunId || randomUUID36()}`
448483
448790
  };
448484
448791
  writeWireMessage(retryMsg);
448485
448792
  } else {
@@ -448500,7 +448807,7 @@ ${loadedContents.join(`
448500
448807
  message: "Tool call ID mismatch; fetching actual pending approvals and resyncing",
448501
448808
  run_id: lastRunId ?? undefined,
448502
448809
  session_id: sessionId,
448503
- uuid: `recovery-${lastRunId || randomUUID35()}`
448810
+ uuid: `recovery-${lastRunId || randomUUID36()}`
448504
448811
  };
448505
448812
  writeWireMessage(recoveryMsg);
448506
448813
  } else {
@@ -448517,7 +448824,7 @@ ${loadedContents.join(`
448517
448824
  stop_reason: stopReason,
448518
448825
  run_id: lastRunId ?? undefined,
448519
448826
  session_id: sessionId,
448520
- uuid: `error-${lastRunId || randomUUID35()}`
448827
+ uuid: `error-${lastRunId || randomUUID36()}`
448521
448828
  };
448522
448829
  await writeWireMessageAsync(errorMsg);
448523
448830
  } else {
@@ -448559,7 +448866,7 @@ ${loadedContents.join(`
448559
448866
  const nudgeMessage = {
448560
448867
  role: "system",
448561
448868
  content: `<system-reminder>The previous response was empty. Please provide a response with either text content or a tool call.</system-reminder>`,
448562
- otid: randomUUID35()
448869
+ otid: randomUUID36()
448563
448870
  };
448564
448871
  currentInput = [...currentInput, nudgeMessage];
448565
448872
  }
@@ -448572,7 +448879,7 @@ ${loadedContents.join(`
448572
448879
  delay_ms: delayMs,
448573
448880
  run_id: lastRunId ?? undefined,
448574
448881
  session_id: sessionId,
448575
- uuid: `retry-empty-${lastRunId || randomUUID35()}`
448882
+ uuid: `retry-empty-${lastRunId || randomUUID36()}`
448576
448883
  };
448577
448884
  writeWireMessage(retryMsg);
448578
448885
  } else {
@@ -448599,7 +448906,7 @@ ${loadedContents.join(`
448599
448906
  delay_ms: delayMs,
448600
448907
  run_id: lastRunId ?? undefined,
448601
448908
  session_id: sessionId,
448602
- uuid: `retry-${lastRunId || randomUUID35()}`
448909
+ uuid: `retry-${lastRunId || randomUUID36()}`
448603
448910
  };
448604
448911
  writeWireMessage(retryMsg);
448605
448912
  } else {
@@ -448629,7 +448936,7 @@ ${loadedContents.join(`
448629
448936
  delay_ms: delayMs,
448630
448937
  run_id: lastRunId ?? undefined,
448631
448938
  session_id: sessionId,
448632
- uuid: `retry-${lastRunId || randomUUID35()}`
448939
+ uuid: `retry-${lastRunId || randomUUID36()}`
448633
448940
  };
448634
448941
  writeWireMessage(retryMsg);
448635
448942
  } else {
@@ -448678,7 +448985,7 @@ ${loadedContents.join(`
448678
448985
  stop_reason: stopReason,
448679
448986
  run_id: lastRunId ?? undefined,
448680
448987
  session_id: sessionId,
448681
- uuid: `error-${lastRunId || randomUUID35()}`
448988
+ uuid: `error-${lastRunId || randomUUID36()}`
448682
448989
  };
448683
448990
  await writeWireMessageAsync(errorMsg);
448684
448991
  } else {
@@ -448697,7 +449004,7 @@ ${loadedContents.join(`
448697
449004
  stop_reason: "error",
448698
449005
  run_id: lastKnownRunId ?? undefined,
448699
449006
  session_id: sessionId,
448700
- uuid: `error-${lastKnownRunId || randomUUID35()}`
449007
+ uuid: `error-${lastKnownRunId || randomUUID36()}`
448701
449008
  };
448702
449009
  await writeWireMessageAsync(errorMsg);
448703
449010
  } else {
@@ -448894,7 +449201,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
448894
449201
  const approvalInput = {
448895
449202
  type: "approval",
448896
449203
  approvals: denialResults,
448897
- otid: randomUUID35()
449204
+ otid: randomUUID36()
448898
449205
  };
448899
449206
  const approvalMessages = [approvalInput];
448900
449207
  {
@@ -448907,7 +449214,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
448907
449214
  type: "text",
448908
449215
  text: sc.content
448909
449216
  })),
448910
- otid: randomUUID35()
449217
+ otid: randomUUID36()
448911
449218
  });
448912
449219
  }
448913
449220
  }
@@ -448965,7 +449272,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
448965
449272
  reason,
448966
449273
  cleared_count: clearedCount,
448967
449274
  session_id: sessionId,
448968
- uuid: `q-clr-${randomUUID35()}`
449275
+ uuid: `q-clr-${randomUUID36()}`
448969
449276
  })
448970
449277
  }
448971
449278
  });
@@ -448995,7 +449302,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
448995
449302
  reason: "runtime_busy",
448996
449303
  queue_len: Math.max(1, queueLen),
448997
449304
  session_id: sessionId,
448998
- uuid: `q-blk-${randomUUID35()}`
449305
+ uuid: `q-blk-${randomUUID36()}`
448999
449306
  });
449000
449307
  }
449001
449308
  function enqueueForTracking(input) {
@@ -449067,7 +449374,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449067
449374
  request_id: interruptRequestId
449068
449375
  },
449069
449376
  session_id: sessionId,
449070
- uuid: randomUUID35()
449377
+ uuid: randomUUID36()
449071
449378
  };
449072
449379
  writeWireMessage(interruptResponse);
449073
449380
  return;
@@ -449170,7 +449477,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449170
449477
  const approvalInput = {
449171
449478
  type: "approval",
449172
449479
  approvals: denialResults,
449173
- otid: randomUUID35()
449480
+ otid: randomUUID36()
449174
449481
  };
449175
449482
  const approvalStream = await sendScopedApprovalMessages({
449176
449483
  agentId: agent.id,
@@ -449209,7 +449516,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449209
449516
  message: "Invalid JSON input",
449210
449517
  stop_reason: "error",
449211
449518
  session_id: sessionId,
449212
- uuid: randomUUID35()
449519
+ uuid: randomUUID36()
449213
449520
  };
449214
449521
  writeWireMessage(errorMsg2);
449215
449522
  continue;
@@ -449235,7 +449542,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449235
449542
  }
449236
449543
  },
449237
449544
  session_id: sessionId,
449238
- uuid: randomUUID35()
449545
+ uuid: randomUUID36()
449239
449546
  };
449240
449547
  writeWireMessage(initResponse);
449241
449548
  } else if (subtype === "interrupt") {
@@ -449252,7 +449559,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449252
449559
  request_id: requestId ?? ""
449253
449560
  },
449254
449561
  session_id: sessionId,
449255
- uuid: randomUUID35()
449562
+ uuid: randomUUID36()
449256
449563
  };
449257
449564
  writeWireMessage(interruptResponse);
449258
449565
  } else if (subtype === "register_external_tools") {
@@ -449300,7 +449607,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449300
449607
  response: { registered: tools.length }
449301
449608
  },
449302
449609
  session_id: sessionId,
449303
- uuid: randomUUID35()
449610
+ uuid: randomUUID36()
449304
449611
  };
449305
449612
  writeWireMessage(registerResponse);
449306
449613
  } else if (subtype === "bootstrap_session_state") {
@@ -449356,7 +449663,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449356
449663
  response: recovery
449357
449664
  },
449358
449665
  session_id: sessionId,
449359
- uuid: randomUUID35()
449666
+ uuid: randomUUID36()
449360
449667
  };
449361
449668
  writeWireMessage(recoveryResponse);
449362
449669
  } catch (error5) {
@@ -449368,7 +449675,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449368
449675
  error: error5 instanceof Error ? error5.message : String(error5)
449369
449676
  },
449370
449677
  session_id: sessionId,
449371
- uuid: randomUUID35()
449678
+ uuid: randomUUID36()
449372
449679
  };
449373
449680
  writeWireMessage(recoveryError);
449374
449681
  }
@@ -449381,7 +449688,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449381
449688
  error: `Unknown control request subtype: ${subtype}`
449382
449689
  },
449383
449690
  session_id: sessionId,
449384
- uuid: randomUUID35()
449691
+ uuid: randomUUID36()
449385
449692
  };
449386
449693
  writeWireMessage(errorResponse);
449387
449694
  }
@@ -449436,7 +449743,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449436
449743
  try {
449437
449744
  const buffers = createBuffers(agent.id);
449438
449745
  const startTime = performance.now();
449439
- const userOtid = randomUUID35();
449746
+ const userOtid = randomUUID36();
449440
449747
  const userTranscriptText = extractTelemetryInputText(userContent);
449441
449748
  if (userTranscriptText.length > 0) {
449442
449749
  const userLineId = `user-${userOtid}`;
@@ -449558,7 +449865,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449558
449865
  recovery_type: "approval_pending",
449559
449866
  message: "Detected pending approval conflict on send; resolving before retry",
449560
449867
  session_id: sessionId,
449561
- uuid: `recovery-bidir-${randomUUID35()}`
449868
+ uuid: `recovery-bidir-${randomUUID36()}`
449562
449869
  };
449563
449870
  writeWireMessage(recoveryMsg);
449564
449871
  await resolveAllPendingApprovals();
@@ -449581,7 +449888,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449581
449888
  max_attempts: LLM_API_ERROR_MAX_RETRIES2,
449582
449889
  delay_ms: delayMs,
449583
449890
  session_id: sessionId,
449584
- uuid: `retry-bidir-${randomUUID35()}`
449891
+ uuid: `retry-bidir-${randomUUID36()}`
449585
449892
  };
449586
449893
  writeWireMessage(retryMsg);
449587
449894
  await new Promise((resolve40) => setTimeout(resolve40, delayMs));
@@ -449603,7 +449910,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449603
449910
  stop_reason: "error",
449604
449911
  run_id: errorInfo.run_id,
449605
449912
  session_id: sessionId,
449606
- uuid: randomUUID35(),
449913
+ uuid: randomUUID36(),
449607
449914
  ...errorInfo.error_type && errorInfo.run_id && {
449608
449915
  api_error: {
449609
449916
  message_type: "error_message",
@@ -449631,7 +449938,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449631
449938
  type: "stream_event",
449632
449939
  event: chunk2,
449633
449940
  session_id: sessionId,
449634
- uuid: uuid3 || randomUUID35()
449941
+ uuid: uuid3 || randomUUID36()
449635
449942
  };
449636
449943
  writeWireMessage(streamEvent);
449637
449944
  } else {
@@ -449639,7 +449946,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449639
449946
  type: "message",
449640
449947
  ...chunk2,
449641
449948
  session_id: sessionId,
449642
- uuid: uuid3 || randomUUID35()
449949
+ uuid: uuid3 || randomUUID36()
449643
449950
  };
449644
449951
  writeWireMessage(msg);
449645
449952
  }
@@ -449708,7 +450015,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449708
450015
  const approvalInputWithOtid = {
449709
450016
  type: "approval",
449710
450017
  approvals: executedResults,
449711
- otid: randomUUID35()
450018
+ otid: randomUUID36()
449712
450019
  };
449713
450020
  currentInput = [approvalInputWithOtid];
449714
450021
  continue;
@@ -449771,7 +450078,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449771
450078
  message: errorDetails,
449772
450079
  stop_reason: "error",
449773
450080
  session_id: sessionId,
449774
- uuid: randomUUID35()
450081
+ uuid: randomUUID36()
449775
450082
  };
449776
450083
  writeWireMessage(errorMsg2);
449777
450084
  const errorResultMsg = {
@@ -449814,7 +450121,7 @@ async function runBidirectionalMode(agent, conversationId, _outputFormat, includ
449814
450121
  message: `Unknown message type: ${message.type}`,
449815
450122
  stop_reason: "error",
449816
450123
  session_id: sessionId,
449817
- uuid: randomUUID35()
450124
+ uuid: randomUUID36()
449818
450125
  };
449819
450126
  writeWireMessage(errorMsg);
449820
450127
  }
@@ -449850,6 +450157,7 @@ var init_headless = __esm(async () => {
449850
450157
  init_reflection_transcript();
449851
450158
  init_local_backend_mod_events();
449852
450159
  init_constants2();
450160
+ init_headless_environment_response();
449853
450161
  init_headless_reflection_settings();
449854
450162
  init_diff_preview();
449855
450163
  init_format_denial();
@@ -451312,7 +451620,7 @@ var init_reflection_arena_hf_upload = __esm(() => {
451312
451620
 
451313
451621
  // src/cli/helpers/reflection-arena.ts
451314
451622
  import { execFile as execFileCb6 } from "node:child_process";
451315
- import { randomInt as randomInt2, randomUUID as randomUUID36 } from "node:crypto";
451623
+ import { randomInt as randomInt2, randomUUID as randomUUID37 } from "node:crypto";
451316
451624
  import { appendFile as appendFile3, mkdir as mkdir18, readFile as readFile30, writeFile as writeFile21 } from "node:fs/promises";
451317
451625
  import { homedir as homedir47 } from "node:os";
451318
451626
  import { join as join85 } from "node:path";
@@ -451674,7 +451982,7 @@ async function startReflectionArenaRun(options) {
451674
451982
  }
451675
451983
  let releaseReservation = true;
451676
451984
  try {
451677
- const runId = randomUUID36().slice(0, 8);
451985
+ const runId = randomUUID37().slice(0, 8);
451678
451986
  const labels = shuffledLabels();
451679
451987
  const prepared = await Promise.all([
451680
451988
  prepareReflectionMemoryWorktreeLaunch({
@@ -464303,22 +464611,6 @@ var init_InputRich = __esm(async () => {
464303
464611
  EventEmitter5.defaultMaxListeners = 20;
464304
464612
  });
464305
464613
 
464306
- // src/backend/api/agents.ts
464307
- async function getAgentContextOverview(agentId, options) {
464308
- return apiRequest("GET", `/v1/agents/${agentId}/context`, undefined, {
464309
- signal: options?.signal
464310
- });
464311
- }
464312
- async function createMinimalAgent(apiKey, name) {
464313
- return apiRequest("POST", "/v1/agents", { name }, {
464314
- baseUrl: "https://api.letta.com",
464315
- apiKey
464316
- });
464317
- }
464318
- var init_agents7 = __esm(() => {
464319
- init_request();
464320
- });
464321
-
464322
464614
  // src/cli/commands/install-github-app.ts
464323
464615
  import { execFileSync as execFileSync7 } from "node:child_process";
464324
464616
  import {
@@ -468704,6 +468996,7 @@ var init_generate_memory_viewer = __esm(() => {
468704
468996
  init_agents7();
468705
468997
  init_client2();
468706
468998
  init_request();
468999
+ init_server_url();
468707
469000
  init_context_usage();
468708
469001
  init_local_memory_context();
468709
469002
  init_memory_viewer_template();
@@ -476777,12 +477070,12 @@ var init_ExitStats = __esm(async () => {
476777
477070
  });
476778
477071
 
476779
477072
  // src/cli/app/ids.ts
476780
- import { randomUUID as randomUUID37 } from "node:crypto";
477073
+ import { randomUUID as randomUUID38 } from "node:crypto";
476781
477074
  function uid(prefix) {
476782
477075
  return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
476783
477076
  }
476784
477077
  function createClientOtid() {
476785
- return randomUUID37();
477078
+ return randomUUID38();
476786
477079
  }
476787
477080
  function appendOptimisticUserLine(buffers, text2, otid) {
476788
477081
  if (!text2) {
@@ -493670,7 +493963,7 @@ var init_notifications = __esm(() => {
493670
493963
  });
493671
493964
 
493672
493965
  // src/cli/app/use-approval-flow.ts
493673
- import { randomUUID as randomUUID38 } from "node:crypto";
493966
+ import { randomUUID as randomUUID39 } from "node:crypto";
493674
493967
  function useApprovalFlow(ctx) {
493675
493968
  const {
493676
493969
  abortControllerRef,
@@ -494182,7 +494475,7 @@ function useApprovalFlow(ctx) {
494182
494475
  {
494183
494476
  type: "approval",
494184
494477
  approvals: allResults,
494185
- otid: randomUUID38()
494478
+ otid: randomUUID39()
494186
494479
  }
494187
494480
  ]);
494188
494481
  } catch (error5) {
@@ -495581,7 +495874,7 @@ var init_system_reminders = __esm(() => {
495581
495874
  });
495582
495875
 
495583
495876
  // src/cli/app/use-conversation-loop.ts
495584
- import { randomUUID as randomUUID39 } from "node:crypto";
495877
+ import { randomUUID as randomUUID40 } from "node:crypto";
495585
495878
  function sleep10(ms) {
495586
495879
  return new Promise((resolve43) => setTimeout(resolve43, ms));
495587
495880
  }
@@ -495885,16 +496178,16 @@ function useConversationLoop(ctx) {
495885
496178
  currentInput = [
495886
496179
  ...lastSentInputRef.current.map((m4) => ({
495887
496180
  ...m4,
495888
- otid: randomUUID39()
496181
+ otid: randomUUID40()
495889
496182
  })),
495890
496183
  ...currentInput.map((m4) => m4.type === "message" && m4.role === "user" ? {
495891
496184
  ...m4,
495892
- otid: randomUUID39(),
496185
+ otid: randomUUID40(),
495893
496186
  content: [
495894
496187
  { type: "text", text: INTERRUPT_RECOVERY_ALERT },
495895
496188
  ...typeof m4.content === "string" ? [{ type: "text", text: m4.content }] : Array.isArray(m4.content) ? m4.content : []
495896
496189
  ]
495897
- } : { ...m4, otid: randomUUID39() })
496190
+ } : { ...m4, otid: randomUUID40() })
495898
496191
  ];
495899
496192
  pendingInterruptRecoveryConversationIdRef.current = null;
495900
496193
  lastSentInputRef.current = [
@@ -495933,7 +496226,7 @@ function useConversationLoop(ctx) {
495933
496226
  type: "text",
495934
496227
  text: sc.content
495935
496228
  })),
495936
- otid: randomUUID39()
496229
+ otid: randomUUID40()
495937
496230
  }
495938
496231
  ];
495939
496232
  }
@@ -496292,7 +496585,7 @@ ${feedback}
496292
496585
  });
496293
496586
  buffersRef.current.order.push(statusId);
496294
496587
  refreshDerived();
496295
- const hookMessageOtid = randomUUID39();
496588
+ const hookMessageOtid = randomUUID40();
496296
496589
  setTimeout(() => {
496297
496590
  processConversation([
496298
496591
  {
@@ -496319,7 +496612,7 @@ ${feedback}
496319
496612
  turnEndContinue = undefined;
496320
496613
  }
496321
496614
  if (turnEndContinue) {
496322
- const continueOtid = randomUUID39();
496615
+ const continueOtid = randomUUID40();
496323
496616
  setTimeout(() => {
496324
496617
  processConversation([
496325
496618
  {
@@ -496673,7 +496966,7 @@ ${feedback}
496673
496966
  {
496674
496967
  type: "approval",
496675
496968
  approvals: allResults,
496676
- otid: randomUUID39()
496969
+ otid: randomUUID40()
496677
496970
  }
496678
496971
  ], {
496679
496972
  allowReentry: true,
@@ -496878,7 +497171,7 @@ ${feedback}
496878
497171
  type: "message",
496879
497172
  role: "system",
496880
497173
  content: `<system-reminder>The previous response was empty. Please provide a response with either text content or a tool call.</system-reminder>`,
496881
- otid: randomUUID39()
497174
+ otid: randomUUID40()
496882
497175
  }
496883
497176
  ];
496884
497177
  }
@@ -497153,7 +497446,7 @@ var init_use_conversation_loop = __esm(async () => {
497153
497446
  });
497154
497447
 
497155
497448
  // src/cli/app/use-conversation-switching.ts
497156
- import { randomUUID as randomUUID40 } from "node:crypto";
497449
+ import { randomUUID as randomUUID41 } from "node:crypto";
497157
497450
  function useConversationSwitching(ctx) {
497158
497451
  const {
497159
497452
  abortControllerRef,
@@ -497228,7 +497521,7 @@ function useConversationSwitching(ctx) {
497228
497521
  {
497229
497522
  role: "user",
497230
497523
  content: question,
497231
- otid: randomUUID40()
497524
+ otid: randomUUID41()
497232
497525
  }
497233
497526
  ];
497234
497527
  let approvalRecoveryRetries = 0;
@@ -497680,7 +497973,7 @@ var init_use_conversation_switching = __esm(async () => {
497680
497973
  init_create5();
497681
497974
  init_defaults();
497682
497975
  init_backend2();
497683
- init_client2();
497976
+ init_server_url();
497684
497977
  init_app_urls();
497685
497978
  init_backfill();
497686
497979
  init_error_formatter();
@@ -502733,7 +503026,7 @@ var init_conversation_switch_alert = __esm(() => {
502733
503026
  });
502734
503027
 
502735
503028
  // src/cli/app/use-submit-handler.ts
502736
- import { randomUUID as randomUUID41 } from "node:crypto";
503029
+ import { randomUUID as randomUUID42 } from "node:crypto";
502737
503030
  import { existsSync as existsSync74, readFileSync as readFileSync46, renameSync as renameSync8, writeFileSync as writeFileSync39 } from "node:fs";
502738
503031
  import { tmpdir as tmpdir13 } from "node:os";
502739
503032
  import { join as join94 } from "node:path";
@@ -503154,7 +503447,7 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
503154
503447
  content: buildTextParts(`${SYSTEM_REMINDER_OPEN}
503155
503448
  ${prompt}
503156
503449
  ${SYSTEM_REMINDER_CLOSE}`),
503157
- otid: randomUUID41()
503450
+ otid: randomUUID42()
503158
503451
  }
503159
503452
  ]);
503160
503453
  } catch (error5) {
@@ -503218,7 +503511,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
503218
503511
  type: "message",
503219
503512
  role: "user",
503220
503513
  content: buildTextParts(buildModCommandPrompt(result3)),
503221
- otid: randomUUID41()
503514
+ otid: randomUUID42()
503222
503515
  }
503223
503516
  ]);
503224
503517
  } else if (result3.type === "output") {
@@ -503263,7 +503556,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
503263
503556
  ${SYSTEM_REMINDER_OPEN}
503264
503557
  ${request2}
503265
503558
  ${SYSTEM_REMINDER_CLOSE}`),
503266
- otid: randomUUID41()
503559
+ otid: randomUUID42()
503267
503560
  }
503268
503561
  ]);
503269
503562
  } catch (error5) {
@@ -503532,7 +503825,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
503532
503825
  ${SYSTEM_REMINDER_OPEN}
503533
503826
  ${request2}
503534
503827
  ${SYSTEM_REMINDER_CLOSE}`),
503535
- otid: randomUUID41()
503828
+ otid: randomUUID42()
503536
503829
  }
503537
503830
  ]);
503538
503831
  } catch (error5) {
@@ -504377,7 +504670,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
504377
504670
  type: "message",
504378
504671
  role: "user",
504379
504672
  content: buildTextParts(skillMessage),
504380
- otid: randomUUID41()
504673
+ otid: randomUUID42()
504381
504674
  }
504382
504675
  ]);
504383
504676
  } catch (error5) {
@@ -504415,7 +504708,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
504415
504708
  type: "message",
504416
504709
  role: "user",
504417
504710
  content: rememberParts,
504418
- otid: randomUUID41()
504711
+ otid: randomUUID42()
504419
504712
  }
504420
504713
  ]);
504421
504714
  } catch (error5) {
@@ -504831,7 +505124,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
504831
505124
  type: "message",
504832
505125
  role: "user",
504833
505126
  content: buildTextParts(initMessage),
504834
- otid: randomUUID41()
505127
+ otid: randomUUID42()
504835
505128
  }
504836
505129
  ]);
504837
505130
  } catch (error5) {
@@ -504998,7 +505291,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
504998
505291
  type: "message",
504999
505292
  role: "user",
505000
505293
  content: buildTextParts(wrapSkillPrompt2(matchedSkill.id, skillContent, userRequest)),
505001
- otid: randomUUID41()
505294
+ otid: randomUUID42()
505002
505295
  }
505003
505296
  ]);
505004
505297
  } catch (error5) {
@@ -505149,7 +505442,7 @@ ${SYSTEM_REMINDER_CLOSE}
505149
505442
  initialInput.push({
505150
505443
  type: "approval",
505151
505444
  approvals: eagerRecoveryDenials,
505152
- otid: randomUUID41()
505445
+ otid: randomUUID42()
505153
505446
  });
505154
505447
  }
505155
505448
  const queuedApprovalInput = consumeQueuedApprovalInputForCurrentConversation();
@@ -512702,4 +512995,4 @@ function registerBunOAuthFlows() {
512702
512995
  registerBunOAuthFlows();
512703
512996
  await init_src5().then(() => exports_src2);
512704
512997
 
512705
- //# debugId=5B21ECF59F212A2E64756E2164756E21
512998
+ //# debugId=39DF2EA197BB152964756E2164756E21