@letta-ai/letta-agent-sdk 0.6.0 → 0.6.2

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.
Files changed (38) hide show
  1. package/README.md +0 -1
  2. package/dist/agent-creation.d.ts +3 -7
  3. package/dist/agent-creation.d.ts.map +1 -1
  4. package/dist/app-server-session.d.ts +0 -5
  5. package/dist/app-server-session.d.ts.map +1 -1
  6. package/dist/client-base.d.ts +4 -1
  7. package/dist/client-base.d.ts.map +1 -1
  8. package/dist/client-entry.js +250 -317
  9. package/dist/client-entry.js.map +12 -12
  10. package/dist/cloud-management.d.ts.map +1 -1
  11. package/dist/cloud-session.d.ts.map +1 -1
  12. package/dist/index.d.ts +2 -4
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +252 -319
  15. package/dist/index.js.map +14 -14
  16. package/dist/management-types.d.ts +3 -0
  17. package/dist/management-types.d.ts.map +1 -1
  18. package/dist/remote-client-session-core.d.ts +22 -2
  19. package/dist/remote-client-session-core.d.ts.map +1 -1
  20. package/dist/remote-turn-coordinator.d.ts +10 -0
  21. package/dist/remote-turn-coordinator.d.ts.map +1 -1
  22. package/dist/tests/advanced-session.d.ts +1 -1
  23. package/dist/tests/advanced-session.d.ts.map +1 -1
  24. package/dist/types.d.ts +0 -21
  25. package/dist/types.d.ts.map +1 -1
  26. package/dist/validation.d.ts.map +1 -1
  27. package/package.json +2 -2
  28. package/src/agent-creation.ts +93 -55
  29. package/src/app-server-session.ts +4 -151
  30. package/src/client-base.ts +7 -4
  31. package/src/cloud-management.ts +18 -1
  32. package/src/cloud-session.ts +3 -1
  33. package/src/index.ts +9 -10
  34. package/src/management-types.ts +3 -0
  35. package/src/remote-client-session-core.ts +35 -5
  36. package/src/remote-turn-coordinator.ts +27 -0
  37. package/src/types.ts +0 -25
  38. package/src/validation.ts +0 -23
@@ -3177,36 +3177,6 @@ function appServerSocketOptions(authToken) {
3177
3177
  }
3178
3178
  return { headers: { Authorization: `Bearer ${token}` } };
3179
3179
  }
3180
- function sameRuntime(a, b) {
3181
- return a?.agent_id === b.agent_id && a?.conversation_id === b.conversation_id;
3182
- }
3183
- function isWaitingLoopStatus(message) {
3184
- return message.loop_status.status === "WAITING_ON_INPUT";
3185
- }
3186
- function isWaitingOnApprovalLoopStatus(message) {
3187
- return message.loop_status.status === "WAITING_ON_APPROVAL";
3188
- }
3189
- function streamDeltaRunId(message) {
3190
- const runId = message.delta.run_id;
3191
- return typeof runId === "string" ? runId : null;
3192
- }
3193
- function streamDeltaMessageType(message) {
3194
- const messageType = message.delta.message_type;
3195
- return typeof messageType === "string" ? messageType : null;
3196
- }
3197
- function streamDeltaStopReason(message) {
3198
- const stopReason = message.delta.stop_reason;
3199
- return typeof stopReason === "string" ? stopReason : null;
3200
- }
3201
- function streamDeltaErrorMessage(message) {
3202
- const delta = message.delta;
3203
- const apiMessage = delta.api_error?.message ?? delta.api_error?.detail;
3204
- if (typeof apiMessage === "string" && apiMessage.length > 0)
3205
- return apiMessage;
3206
- if (typeof delta.message === "string" && delta.message.length > 0)
3207
- return delta.message;
3208
- return "App-server turn failed";
3209
- }
3210
3180
 
3211
3181
  class AppServerClient {
3212
3182
  socket;
@@ -3217,7 +3187,6 @@ class AppServerClient {
3217
3187
  messageHandlers = new Set;
3218
3188
  sendHandlers = new Set;
3219
3189
  disconnectHandlers = new Set;
3220
- activeTurnRuntimes = new Set;
3221
3190
  explicitlyClosed = false;
3222
3191
  disconnectNotified = false;
3223
3192
  nextRequestNumber = 0;
@@ -3400,111 +3369,15 @@ class AppServerClient {
3400
3369
  input(command) {
3401
3370
  this.send({ type: "input", ...command });
3402
3371
  }
3403
- runTurn(command, options = {}) {
3404
- const runtimeKey = `${command.runtime.agent_id}/${command.runtime.conversation_id}`;
3405
- if (this.activeTurnRuntimes.has(runtimeKey)) {
3406
- return Promise.reject(new Error(`A turn is already in flight for ${runtimeKey}`));
3407
- }
3408
- this.activeTurnRuntimes.add(runtimeKey);
3409
- const timeoutMs = options.timeoutMs ?? this.requestTimeoutMs;
3410
- const commandWithIds = this.withClientMessageIds(command);
3411
- const runIds = new Set;
3412
- let observedTurnEvidence = false;
3413
- let observedRequiresApprovalStop = false;
3414
- return new Promise((resolve, reject) => {
3415
- const timeout = setTimeout(() => {
3416
- cleanup();
3417
- reject(new Error(`Timed out waiting for app-server turn on ${command.runtime.agent_id}/${command.runtime.conversation_id}`));
3418
- }, timeoutMs);
3419
- const cleanup = () => {
3420
- clearTimeout(timeout);
3421
- this.activeTurnRuntimes.delete(runtimeKey);
3422
- offMessage();
3423
- };
3424
- const finish = (completedBy, terminalMessage, stopReason) => {
3425
- cleanup();
3426
- resolve({
3427
- runtime: command.runtime,
3428
- stopReason,
3429
- runIds: [...runIds],
3430
- clientMessageIds: commandWithIds.clientMessageIds,
3431
- completedBy,
3432
- terminalMessage
3433
- });
3434
- };
3435
- const fail = (error) => {
3436
- cleanup();
3437
- reject(error);
3438
- };
3439
- const offMessage = this.onMessage((message) => {
3440
- if (!sameRuntime(message.runtime, command.runtime)) {
3441
- return;
3442
- }
3443
- if (message.type === "stream_delta") {
3444
- observedTurnEvidence = true;
3445
- const runId = streamDeltaRunId(message);
3446
- if (runId)
3447
- runIds.add(runId);
3448
- const messageType = streamDeltaMessageType(message);
3449
- if (messageType === "loop_error" || messageType === "error_message") {
3450
- fail(new Error(streamDeltaErrorMessage(message)));
3451
- return;
3452
- }
3453
- if (messageType === "stop_reason") {
3454
- const stopReason = streamDeltaStopReason(message);
3455
- if (stopReason === "requires_approval") {
3456
- observedRequiresApprovalStop = true;
3457
- return;
3458
- }
3459
- finish("stop_reason", message, stopReason);
3460
- }
3461
- return;
3462
- }
3463
- if (message.type === "update_loop_status") {
3464
- const hadTurnEvidenceBeforeLoopStatus = observedTurnEvidence || observedRequiresApprovalStop;
3465
- if (!hadTurnEvidenceBeforeLoopStatus && (isWaitingOnApprovalLoopStatus(message) || options.allowLoopStatusFallback === true && isWaitingLoopStatus(message))) {
3466
- return;
3467
- }
3468
- for (const runId of message.loop_status.active_run_ids) {
3469
- observedTurnEvidence = true;
3470
- runIds.add(runId);
3471
- }
3472
- if (hadTurnEvidenceBeforeLoopStatus && isWaitingOnApprovalLoopStatus(message)) {
3473
- finish("loop_status_waiting_on_approval", message, "requires_approval");
3474
- return;
3475
- }
3476
- if (options.allowLoopStatusFallback === true && hadTurnEvidenceBeforeLoopStatus && isWaitingLoopStatus(message)) {
3477
- finish("loop_status_waiting_fallback", message, null);
3478
- }
3479
- }
3480
- });
3481
- try {
3482
- this.input(commandWithIds.command);
3483
- } catch (error) {
3484
- fail(error instanceof Error ? error : new Error(String(error)));
3485
- }
3486
- });
3487
- }
3488
- withClientMessageIds(command) {
3489
- if (command.payload.kind !== "create_message") {
3490
- return { command, clientMessageIds: [] };
3491
- }
3492
- const clientMessageIds = [];
3493
- const messages = command.payload.messages.map((message) => {
3494
- if (message.role !== "user")
3495
- return message;
3496
- const existing = message.client_message_id;
3497
- const clientMessageId = typeof existing === "string" && existing.length > 0 ? existing : this.nextRequestId("client-message");
3498
- clientMessageIds.push(clientMessageId);
3499
- return { ...message, client_message_id: clientMessageId };
3372
+ submitInput(command, options = {}) {
3373
+ return this.request({
3374
+ type: "input",
3375
+ request_id: command.request_id ?? this.nextRequestId("input"),
3376
+ ...command
3377
+ }, {
3378
+ ...options,
3379
+ predicate: (message) => message.type === "input_accepted"
3500
3380
  });
3501
- return {
3502
- command: {
3503
- ...command,
3504
- payload: { ...command.payload, messages }
3505
- },
3506
- clientMessageIds
3507
- };
3508
3381
  }
3509
3382
  handleMessage(event, channel) {
3510
3383
  const message = parseProtocolMessage(event);
@@ -6438,6 +6311,73 @@ var models_default = {
6438
6311
  parallel_tool_calls: true
6439
6312
  }
6440
6313
  },
6314
+ {
6315
+ id: "opus-5",
6316
+ handle: "anthropic/claude-opus-5",
6317
+ label: "Opus 5",
6318
+ description: "Opus 5 (high reasoning)",
6319
+ updateArgs: {
6320
+ context_window: 200000,
6321
+ max_output_tokens: 128000,
6322
+ enable_reasoner: true,
6323
+ reasoning_effort: "high",
6324
+ parallel_tool_calls: true
6325
+ }
6326
+ },
6327
+ {
6328
+ id: "opus-5-low",
6329
+ handle: "anthropic/claude-opus-5",
6330
+ label: "Opus 5",
6331
+ description: "Opus 5 (low reasoning)",
6332
+ updateArgs: {
6333
+ context_window: 200000,
6334
+ max_output_tokens: 128000,
6335
+ enable_reasoner: true,
6336
+ reasoning_effort: "low",
6337
+ max_reasoning_tokens: 4000,
6338
+ parallel_tool_calls: true
6339
+ }
6340
+ },
6341
+ {
6342
+ id: "opus-5-medium",
6343
+ handle: "anthropic/claude-opus-5",
6344
+ label: "Opus 5",
6345
+ description: "Opus 5 (med reasoning)",
6346
+ updateArgs: {
6347
+ context_window: 200000,
6348
+ max_output_tokens: 128000,
6349
+ enable_reasoner: true,
6350
+ reasoning_effort: "medium",
6351
+ max_reasoning_tokens: 12000,
6352
+ parallel_tool_calls: true
6353
+ }
6354
+ },
6355
+ {
6356
+ id: "opus-5-xhigh",
6357
+ handle: "anthropic/claude-opus-5",
6358
+ label: "Opus 5",
6359
+ description: "Opus 5 (extra-high reasoning)",
6360
+ updateArgs: {
6361
+ context_window: 200000,
6362
+ max_output_tokens: 128000,
6363
+ enable_reasoner: true,
6364
+ reasoning_effort: "xhigh",
6365
+ parallel_tool_calls: true
6366
+ }
6367
+ },
6368
+ {
6369
+ id: "opus-5-max",
6370
+ handle: "anthropic/claude-opus-5",
6371
+ label: "Opus 5",
6372
+ description: "Opus 5 (max reasoning)",
6373
+ updateArgs: {
6374
+ context_window: 200000,
6375
+ max_output_tokens: 128000,
6376
+ enable_reasoner: true,
6377
+ reasoning_effort: "max",
6378
+ parallel_tool_calls: true
6379
+ }
6380
+ },
6441
6381
  {
6442
6382
  id: "opus",
6443
6383
  handle: "anthropic/claude-opus-4-8",
@@ -6712,7 +6652,7 @@ var models_default = {
6712
6652
  id: "sonnet-5-xhigh",
6713
6653
  handle: "anthropic/claude-sonnet-5",
6714
6654
  label: "Sonnet 5",
6715
- description: "Sonnet 5 (max reasoning)",
6655
+ description: "Sonnet 5 (extra-high reasoning)",
6716
6656
  updateArgs: {
6717
6657
  context_window: 1e6,
6718
6658
  max_output_tokens: 128000,
@@ -6721,6 +6661,19 @@ var models_default = {
6721
6661
  parallel_tool_calls: true
6722
6662
  }
6723
6663
  },
6664
+ {
6665
+ id: "sonnet-5-max",
6666
+ handle: "anthropic/claude-sonnet-5",
6667
+ label: "Sonnet 5",
6668
+ description: "Sonnet 5 (max reasoning)",
6669
+ updateArgs: {
6670
+ context_window: 1e6,
6671
+ max_output_tokens: 128000,
6672
+ reasoning_effort: "max",
6673
+ enable_reasoner: true,
6674
+ parallel_tool_calls: true
6675
+ }
6676
+ },
6724
6677
  {
6725
6678
  id: "sonnet-4.6",
6726
6679
  handle: "anthropic/claude-sonnet-4-6",
@@ -8271,7 +8224,6 @@ var models_default = {
8271
8224
  ]
8272
8225
  };
8273
8226
  var models = models_default.models;
8274
- var MODEL_PRESETS = models;
8275
8227
  function resolveModel(modelIdentifier) {
8276
8228
  const byId = models.find((m) => m.id === modelIdentifier);
8277
8229
  if (byId)
@@ -8499,75 +8451,128 @@ function buildPersonalityMemoryBlocks(personalityId, defaultMemoryBlocks, enviro
8499
8451
  }
8500
8452
  var LETTA_CODE_AGENT_TYPE = "letta_v1_agent";
8501
8453
  var DEFAULT_CREATED_AGENT_BASE_TOOLS = ["web_search", "fetch_webpage"];
8502
- async function buildCreateAgentRequestForPersonality(params) {
8503
- const { personalityId, name, description, model, extraTags } = params;
8504
- const personality = getPersonalityOption(personalityId);
8505
- const modelIdentifier = model ?? personality.defaultModel;
8454
+ function mergeMemoryBlocks(base, overrides) {
8455
+ const blocks = base.map((block) => ({ ...block }));
8456
+ for (const override of overrides ?? []) {
8457
+ const index = blocks.findIndex((block) => block.label === override.label);
8458
+ if (index >= 0) {
8459
+ blocks[index] = { ...override };
8460
+ } else {
8461
+ blocks.push({ ...override });
8462
+ }
8463
+ }
8464
+ return blocks;
8465
+ }
8466
+ async function buildCreateAgentRequest(options = {}) {
8467
+ const personality = options.personalityId ? getPersonalityOption(options.personalityId) : undefined;
8468
+ const modelIdentifier = options.model ?? personality?.defaultModel;
8506
8469
  const modelHandle = modelIdentifier ? resolveModel(modelIdentifier) : getDefaultModel();
8507
8470
  if (!modelHandle) {
8508
8471
  throw new Error(`Unknown model: ${modelIdentifier}`);
8509
8472
  }
8510
- const defaultMemoryBlocks = await getDefaultMemoryBlocks();
8473
+ if (!options.isSubagent && options.enableMemfs !== undefined && options.memoryPromptMode !== undefined && options.enableMemfs !== (options.memoryPromptMode !== "standard")) {
8474
+ throw new Error("enableMemfs and memoryPromptMode must describe the same memory mode");
8475
+ }
8476
+ const enableMemfs = options.isSubagent ? false : options.enableMemfs ?? options.memoryPromptMode !== "standard";
8477
+ const memoryPromptMode = options.isSubagent ? "standard" : options.memoryPromptMode ?? (enableMemfs ? "memfs" : "standard");
8478
+ const personalityTags = options.personalityId ? getPersonalityCreationTags(options.personalityId) : [];
8479
+ const personalityBlocks = options.personalityId ? buildPersonalityMemoryBlocks(options.personalityId, await getDefaultMemoryBlocks()) : [];
8480
+ const memoryBlocks = options.isSubagent ? undefined : options.personalityId || options.memoryBlocks !== undefined ? mergeMemoryBlocks(personalityBlocks, options.memoryBlocks) : undefined;
8481
+ const blockIds = options.isSubagent ? undefined : options.blockIds;
8511
8482
  return {
8512
8483
  agent_type: LETTA_CODE_AGENT_TYPE,
8513
- name: name ?? personality.label,
8514
- description: description ?? personality.description,
8484
+ ...options.name !== undefined || personality ? { name: options.name ?? personality?.label } : {},
8485
+ ...options.description !== undefined || personality ? { description: options.description ?? personality?.description } : {},
8515
8486
  model: modelHandle,
8516
- system: buildSystemPrompt("default", "memfs"),
8517
- memory_blocks: buildPersonalityMemoryBlocks(personalityId, defaultMemoryBlocks),
8487
+ system: options.system ?? buildSystemPrompt("default", memoryPromptMode),
8488
+ ...memoryBlocks !== undefined ? { memory_blocks: memoryBlocks } : {},
8489
+ ...blockIds && blockIds.length > 0 ? { block_ids: blockIds } : {},
8518
8490
  tags: buildCreatedAgentTags({
8519
- enableMemfs: true,
8520
- tags: [
8521
- ...getPersonalityCreationTags(personalityId),
8522
- ...extraTags ?? []
8523
- ]
8491
+ enableMemfs,
8492
+ isSubagent: options.isSubagent,
8493
+ tags: [...personalityTags, ...options.extraTags ?? []]
8524
8494
  }),
8525
- tools: [...DEFAULT_CREATED_AGENT_BASE_TOOLS],
8495
+ tools: [...options.baseTools ?? DEFAULT_CREATED_AGENT_BASE_TOOLS],
8526
8496
  include_base_tools: false,
8527
8497
  include_base_tool_rules: false,
8528
8498
  initial_message_sequence: [],
8529
- parallel_tool_calls: true,
8530
- compaction_settings: { model: DEFAULT_SUMMARIZATION_MODEL }
8499
+ parallel_tool_calls: options.parallelToolCalls ?? true,
8500
+ compaction_settings: {
8501
+ model: options.compactionModel ?? DEFAULT_SUMMARIZATION_MODEL
8502
+ },
8503
+ ...options.embedding !== undefined ? { embedding: options.embedding } : {},
8504
+ ...options.isSubagent ? { hidden: true } : options.hidden !== undefined ? { hidden: options.hidden } : {}
8531
8505
  };
8532
8506
  }
8533
8507
 
8534
8508
  // src/agent-creation.ts
8535
- var DEFAULT_MODEL_ID = "auto";
8536
- var DEFAULT_SUMMARIZATION_MODEL2 = "letta/auto";
8537
- function resolveModel2(modelIdentifier) {
8538
- const preset = MODEL_PRESETS.find((model) => model.id === modelIdentifier || model.handle === modelIdentifier);
8539
- if (preset)
8540
- return preset.handle;
8541
- if (modelIdentifier.includes("/"))
8542
- return modelIdentifier;
8543
- throw new Error(`Unknown model: ${modelIdentifier}`);
8509
+ function isPresetSystemPrompt(value) {
8510
+ return [
8511
+ "default",
8512
+ "letta-claude",
8513
+ "letta-codex",
8514
+ "letta-gemini",
8515
+ "claude",
8516
+ "codex",
8517
+ "gemini"
8518
+ ].includes(value);
8544
8519
  }
8545
- async function buildInitialAgentBody(options) {
8546
- if (options.personality !== undefined) {
8547
- return {
8548
- ...await buildCreateAgentRequestForPersonality({
8549
- personalityId: options.personality,
8550
- ...options.name !== undefined ? { name: options.name } : {},
8551
- ...options.description !== undefined ? { description: options.description } : {},
8552
- ...options.model !== undefined ? { model: options.model } : {},
8553
- ...options.tags !== undefined ? { extraTags: options.tags } : {}
8554
- })
8555
- };
8520
+ function assertCreateAgentOptionsSupported(options) {
8521
+ if (options.allowedTools !== undefined || options.disallowedTools !== undefined) {
8522
+ throw new Error("App-server createAgent() does not yet support allowedTools/disallowedTools.");
8523
+ }
8524
+ if (options.canUseTool !== undefined) {
8525
+ throw new Error("App-server createAgent() does not yet support canUseTool callbacks.");
8526
+ }
8527
+ if (options.systemInfoReminder !== undefined) {
8528
+ throw new Error("App-server createAgent() does not yet support systemInfoReminder overrides.");
8529
+ }
8530
+ if (options.dreaming?.behavior !== undefined) {
8531
+ throw new Error("App-server createAgent() does not yet support dreaming.behavior overrides.");
8556
8532
  }
8557
- return {
8558
- agent_type: LETTA_CODE_AGENT_TYPE,
8559
- ...options.name !== undefined ? { name: options.name } : {},
8560
- ...options.description !== undefined ? { description: options.description } : {},
8561
- model: resolveModel2(options.model ?? DEFAULT_MODEL_ID),
8562
- system: buildSystemPrompt("default", "memfs"),
8563
- tags: buildCreatedAgentTags({
8564
- enableMemfs: true,
8565
- tags: options.tags ?? []
8566
- }),
8567
- initial_message_sequence: [],
8568
- parallel_tool_calls: true,
8569
- compaction_settings: { model: DEFAULT_SUMMARIZATION_MODEL2 }
8570
- };
8533
+ }
8534
+ async function createAgentBody(options) {
8535
+ assertCreateAgentOptionsSupported(options);
8536
+ let system;
8537
+ if (options.systemPrompt !== undefined) {
8538
+ if (typeof options.systemPrompt !== "string" || isPresetSystemPrompt(options.systemPrompt)) {
8539
+ throw new Error("createAgent() does not yet support system prompt presets for this backend.");
8540
+ }
8541
+ system = options.systemPrompt;
8542
+ }
8543
+ const memoryBlocks = [];
8544
+ const blockIds = [];
8545
+ for (const item of options.memory ?? []) {
8546
+ if (typeof item === "string") {
8547
+ throw new Error("App-server createAgent() does not yet support memory preset names.");
8548
+ }
8549
+ if ("blockId" in item) {
8550
+ blockIds.push(item.blockId);
8551
+ } else {
8552
+ memoryBlocks.push({ ...item });
8553
+ }
8554
+ }
8555
+ if (options.persona !== undefined) {
8556
+ memoryBlocks.push({ label: "persona", value: options.persona });
8557
+ }
8558
+ if (options.human !== undefined) {
8559
+ memoryBlocks.push({ label: "human", value: options.human });
8560
+ }
8561
+ const hasMemoryConfiguration = options.memory !== undefined || options.persona !== undefined || options.human !== undefined;
8562
+ return buildCreateAgentRequest({
8563
+ personalityId: options.personality,
8564
+ name: options.name,
8565
+ description: options.description,
8566
+ model: options.model,
8567
+ system,
8568
+ memoryBlocks: hasMemoryConfiguration ? memoryBlocks : undefined,
8569
+ blockIds,
8570
+ extraTags: options.tags,
8571
+ enableMemfs: options.memfs ?? true,
8572
+ baseTools: options.baseTools,
8573
+ embedding: options.embedding,
8574
+ hidden: options.hidden
8575
+ });
8571
8576
  }
8572
8577
 
8573
8578
  // src/interactiveToolPolicy.ts
@@ -8856,7 +8861,7 @@ function firstToolReturn(delta) {
8856
8861
  }
8857
8862
  return;
8858
8863
  }
8859
- function sameRuntime2(message, runtime) {
8864
+ function sameRuntime(message, runtime) {
8860
8865
  const msgRuntime = message.runtime;
8861
8866
  if (msgRuntime) {
8862
8867
  return msgRuntime.agent_id === runtime.agent_id && msgRuntime.conversation_id === runtime.conversation_id;
@@ -8875,10 +8880,10 @@ function streamDeltaRecord(message) {
8875
8880
  const delta = message.delta;
8876
8881
  return delta && typeof delta === "object" && !Array.isArray(delta) ? delta : null;
8877
8882
  }
8878
- function streamDeltaMessageType2(delta) {
8883
+ function streamDeltaMessageType(delta) {
8879
8884
  return typeof delta.message_type === "string" ? delta.message_type : undefined;
8880
8885
  }
8881
- function streamDeltaRunId2(delta) {
8886
+ function streamDeltaRunId(delta) {
8882
8887
  return typeof delta.run_id === "string" ? delta.run_id : undefined;
8883
8888
  }
8884
8889
  function streamDeltaOtid(delta) {
@@ -8887,7 +8892,7 @@ function streamDeltaOtid(delta) {
8887
8892
  function streamDeltaSeqId(delta) {
8888
8893
  return typeof delta.seq_id === "number" ? delta.seq_id : undefined;
8889
8894
  }
8890
- function streamDeltaStopReason2(delta) {
8895
+ function streamDeltaStopReason(delta) {
8891
8896
  return typeof delta.stop_reason === "string" ? delta.stop_reason : undefined;
8892
8897
  }
8893
8898
  function loopStatusRecord(message) {
@@ -9110,7 +9115,7 @@ class RemoteTurnCoordinator {
9110
9115
  this.activeTurn.abortRequested = true;
9111
9116
  }
9112
9117
  handleProtocolMessage(message, runtime) {
9113
- if (!sameRuntime2(message, runtime))
9118
+ if (!sameRuntime(message, runtime))
9114
9119
  return;
9115
9120
  const statusRecord = deviceStatusRecord(message);
9116
9121
  if (statusRecord) {
@@ -9137,7 +9142,7 @@ class RemoteTurnCoordinator {
9137
9142
  const active = this.activateNextTurnFromProtocol();
9138
9143
  if (active) {
9139
9144
  active.observedTurnEvidence = true;
9140
- const runId = streamDeltaRunId2(delta);
9145
+ const runId = streamDeltaRunId(delta);
9141
9146
  if (runId)
9142
9147
  active.runIds.add(runId);
9143
9148
  }
@@ -9156,6 +9161,24 @@ class RemoteTurnCoordinator {
9156
9161
  this.streamResolvers.push(resolve);
9157
9162
  });
9158
9163
  }
9164
+ closeWithError(detail) {
9165
+ if (this.closed)
9166
+ return;
9167
+ const active = this.activeTurn;
9168
+ if (active) {
9169
+ this.failTurn(active, detail);
9170
+ } else {
9171
+ this.enqueue({
9172
+ type: "error",
9173
+ message: detail,
9174
+ errorCode: "error",
9175
+ stopReason: "error",
9176
+ errorDetail: detail,
9177
+ recoverable: false
9178
+ });
9179
+ }
9180
+ this.close();
9181
+ }
9159
9182
  close() {
9160
9183
  if (this.closed)
9161
9184
  return;
@@ -9273,9 +9296,9 @@ class RemoteTurnCoordinator {
9273
9296
  const active = this.activeTurn;
9274
9297
  if (!active)
9275
9298
  return;
9276
- const messageType = streamDeltaMessageType2(delta);
9299
+ const messageType = streamDeltaMessageType(delta);
9277
9300
  if (messageType === "stop_reason") {
9278
- const stopReason = streamDeltaStopReason2(delta) ?? null;
9301
+ const stopReason = streamDeltaStopReason(delta) ?? null;
9279
9302
  if (stopReason === "requires_approval") {
9280
9303
  active.observedRequiresApprovalStop = true;
9281
9304
  return;
@@ -9469,6 +9492,7 @@ class RemoteClientSessionCore {
9469
9492
  requestTimeoutMs;
9470
9493
  initializePromise = null;
9471
9494
  removeMessageHandler = null;
9495
+ detachTransportDisconnect = null;
9472
9496
  turns;
9473
9497
  toolNames;
9474
9498
  deviceStatusListeners = new Set;
@@ -9543,6 +9567,8 @@ class RemoteClientSessionCore {
9543
9567
  cleanupFailedInitialize() {
9544
9568
  this.removeMessageHandler?.();
9545
9569
  this.removeMessageHandler = null;
9570
+ this.detachTransportDisconnect?.();
9571
+ this.detachTransportDisconnect = null;
9546
9572
  this.controller?.close();
9547
9573
  this.controller = null;
9548
9574
  this.onCoreClose();
@@ -9573,7 +9599,7 @@ class RemoteClientSessionCore {
9573
9599
  throw error;
9574
9600
  }
9575
9601
  }
9576
- async runTurn(message, _options = {}) {
9602
+ async sendAndWaitForResult(message) {
9577
9603
  if (this.turns.hasInFlightTurn()) {
9578
9604
  throw new Error(`A turn is already in flight for this ${this.label} session. Use send() and stream() to let the listener queue messages.`);
9579
9605
  }
@@ -9830,6 +9856,8 @@ class RemoteClientSessionCore {
9830
9856
  this.closed = true;
9831
9857
  this.removeMessageHandler?.();
9832
9858
  this.removeMessageHandler = null;
9859
+ this.detachTransportDisconnect?.();
9860
+ this.detachTransportDisconnect = null;
9833
9861
  this.turns.close();
9834
9862
  for (const cancel of [...this.deviceStatusRefreshCancels]) {
9835
9863
  cancel(new Error(`Session closed while waiting for ${this.label} device status`));
@@ -9890,6 +9918,15 @@ class RemoteClientSessionCore {
9890
9918
  }, { predicate: (message) => message.type === "update_toolset_response" });
9891
9919
  ensureSuccess(response, "Failed to update toolset");
9892
9920
  }
9921
+ watchTransportDisconnect(client) {
9922
+ this.detachTransportDisconnect?.();
9923
+ this.detachTransportDisconnect = client.onDisconnect(() => {
9924
+ if (this.closed)
9925
+ return;
9926
+ this.turns.closeWithError(`The ${this.label} connection closed unexpectedly; resume the conversation to continue.`);
9927
+ this.close();
9928
+ });
9929
+ }
9893
9930
  async afterRuntimeInitialized() {}
9894
9931
  async beforeTurn() {}
9895
9932
  onCoreClose() {}
@@ -10011,111 +10048,6 @@ function agentToolNames(agent) {
10011
10048
  return typeof name === "string" && name.length > 0 ? [name] : [];
10012
10049
  });
10013
10050
  }
10014
- function isPresetSystemPrompt(value) {
10015
- return [
10016
- "default",
10017
- "letta-claude",
10018
- "letta-codex",
10019
- "letta-gemini",
10020
- "claude",
10021
- "codex",
10022
- "gemini"
10023
- ].includes(value);
10024
- }
10025
- function assertRemoteCreateAgentOptionsSupported(options) {
10026
- if (options.allowedTools !== undefined || options.disallowedTools !== undefined) {
10027
- throw new Error("App-server createAgent() does not yet support allowedTools/disallowedTools.");
10028
- }
10029
- if (options.canUseTool !== undefined) {
10030
- throw new Error("App-server createAgent() does not yet support canUseTool callbacks.");
10031
- }
10032
- if (options.systemInfoReminder !== undefined) {
10033
- throw new Error("App-server createAgent() does not yet support systemInfoReminder overrides.");
10034
- }
10035
- if (options.dreaming?.behavior !== undefined) {
10036
- throw new Error("App-server createAgent() does not yet support dreaming.behavior overrides.");
10037
- }
10038
- }
10039
- function normalizeMemoryBlock(block) {
10040
- const normalized = { ...block };
10041
- if (normalized.value === undefined && typeof normalized.content === "string") {
10042
- normalized.value = normalized.content;
10043
- }
10044
- return normalized;
10045
- }
10046
- function upsertMemoryBlock(blocks, block) {
10047
- const label = block.label;
10048
- if (typeof label === "string") {
10049
- const existingIndex = blocks.findIndex((candidate) => candidate.label === label);
10050
- if (existingIndex >= 0) {
10051
- blocks[existingIndex] = block;
10052
- return;
10053
- }
10054
- }
10055
- blocks.push(block);
10056
- }
10057
- async function createAgentBody(options, settings = {}) {
10058
- assertRemoteCreateAgentOptionsSupported(options);
10059
- const includeOriginTag = settings.includeSdkOriginTag ?? true;
10060
- const body = await buildInitialAgentBody(options);
10061
- if (Array.isArray(body.tags)) {
10062
- body.tags = body.tags.filter((tag) => (includeOriginTag || tag !== LETTA_CODE_ORIGIN_TAG) && (options.memfs !== false || tag !== GIT_MEMORY_ENABLED_TAG));
10063
- }
10064
- if (options.embedding !== undefined)
10065
- body.embedding = options.embedding;
10066
- if (options.hidden !== undefined)
10067
- body.hidden = options.hidden;
10068
- if (options.baseTools === undefined) {
10069
- delete body.tools;
10070
- delete body.include_base_tools;
10071
- delete body.include_base_tool_rules;
10072
- } else {
10073
- body.tools = options.baseTools;
10074
- body.include_base_tools = false;
10075
- body.include_base_tool_rules = false;
10076
- }
10077
- if (options.systemPrompt === undefined) {
10078
- if (options.memfs === false) {
10079
- body.system = buildSystemPrompt("default", "standard");
10080
- }
10081
- } else {
10082
- if (typeof options.systemPrompt === "string") {
10083
- if (isPresetSystemPrompt(options.systemPrompt)) {
10084
- throw new Error("createAgent() does not yet support system prompt presets for this backend.");
10085
- }
10086
- body.system = options.systemPrompt;
10087
- } else {
10088
- throw new Error("createAgent() does not yet support system prompt preset objects for this backend.");
10089
- }
10090
- }
10091
- const hasMemoryConfiguration = Array.isArray(body.memory_blocks) || options.memory !== undefined || options.persona !== undefined || options.human !== undefined;
10092
- const memoryBlocks = Array.isArray(body.memory_blocks) ? body.memory_blocks.filter((block) => block !== null && typeof block === "object").map((block) => ({ ...block })) : [];
10093
- const blockIds = [];
10094
- for (const item of options.memory ?? []) {
10095
- if (typeof item === "string") {
10096
- throw new Error("App-server createAgent() does not yet support memory preset names.");
10097
- }
10098
- if ("blockId" in item) {
10099
- blockIds.push(item.blockId);
10100
- } else {
10101
- upsertMemoryBlock(memoryBlocks, normalizeMemoryBlock(item));
10102
- }
10103
- }
10104
- if (options.persona !== undefined) {
10105
- upsertMemoryBlock(memoryBlocks, {
10106
- label: "persona",
10107
- value: options.persona
10108
- });
10109
- }
10110
- if (options.human !== undefined) {
10111
- upsertMemoryBlock(memoryBlocks, { label: "human", value: options.human });
10112
- }
10113
- if (hasMemoryConfiguration)
10114
- body.memory_blocks = memoryBlocks;
10115
- if (blockIds.length > 0)
10116
- body.block_ids = blockIds;
10117
- return body;
10118
- }
10119
10051
  function externalToolGroups(tools) {
10120
10052
  if (!tools || tools.length === 0)
10121
10053
  return;
@@ -10494,6 +10426,7 @@ class AppServerSession extends RemoteClientSessionCore {
10494
10426
  if (!response.success || !response.runtime) {
10495
10427
  throw new Error(response.error ?? "Failed to start app-server runtime");
10496
10428
  }
10429
+ this.watchTransportDisconnect(client);
10497
10430
  const tools = agentToolNames(response.agent);
10498
10431
  const skillSources = options.skillSources;
10499
10432
  const clientToolset = "toolset" in options ? options.toolset : undefined;
@@ -10576,9 +10509,7 @@ class AppServerSession extends RemoteClientSessionCore {
10576
10509
  command.external_tools = groups;
10577
10510
  if (this.mode.kind === "create-agent") {
10578
10511
  command.create_agent = {
10579
- body: await createAgentBody(this.mode.options, {
10580
- includeSdkOriginTag: this.remoteOptions.includeSdkOriginTag
10581
- }),
10512
+ body: await createAgentBody(this.mode.options),
10582
10513
  pin_global: this.remoteOptions.pinGlobalAgent ?? this.mode.options.hidden !== true,
10583
10514
  ...this.mode.options.memfs === false ? { memfs: false } : {}
10584
10515
  };
@@ -10649,6 +10580,16 @@ function cloudModelEntry(raw) {
10649
10580
  function isNotFound(error) {
10650
10581
  return error instanceof APIError && error.status === 404;
10651
10582
  }
10583
+ function toOrderRelativeCursors(query) {
10584
+ if ((query.order ?? "desc") !== "desc")
10585
+ return query;
10586
+ const { before, after, ...rest } = query;
10587
+ return {
10588
+ ...rest,
10589
+ ...after != null ? { before: after } : {},
10590
+ ...before != null ? { after: before } : {}
10591
+ };
10592
+ }
10652
10593
 
10653
10594
  class CloudManagementTransport {
10654
10595
  client;
@@ -10724,7 +10665,7 @@ class CloudManagementTransport {
10724
10665
  return this.client.conversations.update(conversationId, body);
10725
10666
  }
10726
10667
  async listConversationMessages(conversationId, query) {
10727
- const page = await this.client.conversations.messages.list(conversationId, query);
10668
+ const page = await this.client.conversations.messages.list(conversationId, toOrderRelativeCursors(query));
10728
10669
  return { messages: page.items };
10729
10670
  }
10730
10671
  }
@@ -11263,6 +11204,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
11263
11204
  if (!response.success || !response.runtime) {
11264
11205
  throw new Error(response.error ?? "Failed to start Cloud status runtime");
11265
11206
  }
11207
+ this.watchTransportDisconnect(client);
11266
11208
  const tools = agentToolNames(response.agent);
11267
11209
  const skillSources = options.skillSources;
11268
11210
  const clientToolset = "toolset" in options ? options.toolset : undefined;
@@ -11808,14 +11750,6 @@ function getBlockLabels(memory) {
11808
11750
  return null;
11809
11751
  }).filter((label) => label !== null);
11810
11752
  }
11811
- function validateApprovalRecoveryOptions(options) {
11812
- if (options.maxApprovalRecoveryAttempts !== undefined && (!Number.isInteger(options.maxApprovalRecoveryAttempts) || options.maxApprovalRecoveryAttempts < 0)) {
11813
- throw new Error("Invalid maxApprovalRecoveryAttempts. Expected a non-negative integer.");
11814
- }
11815
- if (options.approvalRecoveryTimeoutMs !== undefined && (!Number.isInteger(options.approvalRecoveryTimeoutMs) || options.approvalRecoveryTimeoutMs <= 0)) {
11816
- throw new Error("Invalid approvalRecoveryTimeoutMs. Expected a positive integer.");
11817
- }
11818
- }
11819
11753
  function validateRemovedSessionOptions(options) {
11820
11754
  const removedOptions = options;
11821
11755
  if (removedOptions.systemPrompt !== undefined) {
@@ -11928,7 +11862,6 @@ function validateCreateSessionOptions(options) {
11928
11862
  validateMcpServers(options.mcpServers);
11929
11863
  validateReasoningEffort(options.reasoningEffort);
11930
11864
  validateDreamingOptions(options.dreaming);
11931
- validateApprovalRecoveryOptions(options);
11932
11865
  validateRemovedSessionOptions(options);
11933
11866
  }
11934
11867
  function validateCreateAgentOptions(options) {
@@ -12136,7 +12069,7 @@ class LettaAgentClientBase {
12136
12069
  async prompt(message, agentId, options = {}) {
12137
12070
  const session = this.createSession(agentId, options);
12138
12071
  try {
12139
- return await session.runTurn(message);
12072
+ return await session.sendAndWaitForResult(message);
12140
12073
  } finally {
12141
12074
  session.close();
12142
12075
  }
@@ -12354,4 +12287,4 @@ export {
12354
12287
  CloudManagedSandboxExpiredError
12355
12288
  };
12356
12289
 
12357
- //# debugId=FE3D4D568E602DA664756E2164756E21
12290
+ //# debugId=B03015C0FF639CFA64756E2164756E21