@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
package/dist/index.js CHANGED
@@ -3195,36 +3195,6 @@ function appServerSocketOptions(authToken) {
3195
3195
  }
3196
3196
  return { headers: { Authorization: `Bearer ${token}` } };
3197
3197
  }
3198
- function sameRuntime(a, b) {
3199
- return a?.agent_id === b.agent_id && a?.conversation_id === b.conversation_id;
3200
- }
3201
- function isWaitingLoopStatus(message) {
3202
- return message.loop_status.status === "WAITING_ON_INPUT";
3203
- }
3204
- function isWaitingOnApprovalLoopStatus(message) {
3205
- return message.loop_status.status === "WAITING_ON_APPROVAL";
3206
- }
3207
- function streamDeltaRunId(message) {
3208
- const runId = message.delta.run_id;
3209
- return typeof runId === "string" ? runId : null;
3210
- }
3211
- function streamDeltaMessageType(message) {
3212
- const messageType = message.delta.message_type;
3213
- return typeof messageType === "string" ? messageType : null;
3214
- }
3215
- function streamDeltaStopReason(message) {
3216
- const stopReason = message.delta.stop_reason;
3217
- return typeof stopReason === "string" ? stopReason : null;
3218
- }
3219
- function streamDeltaErrorMessage(message) {
3220
- const delta = message.delta;
3221
- const apiMessage = delta.api_error?.message ?? delta.api_error?.detail;
3222
- if (typeof apiMessage === "string" && apiMessage.length > 0)
3223
- return apiMessage;
3224
- if (typeof delta.message === "string" && delta.message.length > 0)
3225
- return delta.message;
3226
- return "App-server turn failed";
3227
- }
3228
3198
 
3229
3199
  class AppServerClient {
3230
3200
  socket;
@@ -3235,7 +3205,6 @@ class AppServerClient {
3235
3205
  messageHandlers = new Set;
3236
3206
  sendHandlers = new Set;
3237
3207
  disconnectHandlers = new Set;
3238
- activeTurnRuntimes = new Set;
3239
3208
  explicitlyClosed = false;
3240
3209
  disconnectNotified = false;
3241
3210
  nextRequestNumber = 0;
@@ -3418,111 +3387,15 @@ class AppServerClient {
3418
3387
  input(command) {
3419
3388
  this.send({ type: "input", ...command });
3420
3389
  }
3421
- runTurn(command, options = {}) {
3422
- const runtimeKey = `${command.runtime.agent_id}/${command.runtime.conversation_id}`;
3423
- if (this.activeTurnRuntimes.has(runtimeKey)) {
3424
- return Promise.reject(new Error(`A turn is already in flight for ${runtimeKey}`));
3425
- }
3426
- this.activeTurnRuntimes.add(runtimeKey);
3427
- const timeoutMs = options.timeoutMs ?? this.requestTimeoutMs;
3428
- const commandWithIds = this.withClientMessageIds(command);
3429
- const runIds = new Set;
3430
- let observedTurnEvidence = false;
3431
- let observedRequiresApprovalStop = false;
3432
- return new Promise((resolve, reject) => {
3433
- const timeout = setTimeout(() => {
3434
- cleanup();
3435
- reject(new Error(`Timed out waiting for app-server turn on ${command.runtime.agent_id}/${command.runtime.conversation_id}`));
3436
- }, timeoutMs);
3437
- const cleanup = () => {
3438
- clearTimeout(timeout);
3439
- this.activeTurnRuntimes.delete(runtimeKey);
3440
- offMessage();
3441
- };
3442
- const finish = (completedBy, terminalMessage, stopReason) => {
3443
- cleanup();
3444
- resolve({
3445
- runtime: command.runtime,
3446
- stopReason,
3447
- runIds: [...runIds],
3448
- clientMessageIds: commandWithIds.clientMessageIds,
3449
- completedBy,
3450
- terminalMessage
3451
- });
3452
- };
3453
- const fail = (error) => {
3454
- cleanup();
3455
- reject(error);
3456
- };
3457
- const offMessage = this.onMessage((message) => {
3458
- if (!sameRuntime(message.runtime, command.runtime)) {
3459
- return;
3460
- }
3461
- if (message.type === "stream_delta") {
3462
- observedTurnEvidence = true;
3463
- const runId = streamDeltaRunId(message);
3464
- if (runId)
3465
- runIds.add(runId);
3466
- const messageType = streamDeltaMessageType(message);
3467
- if (messageType === "loop_error" || messageType === "error_message") {
3468
- fail(new Error(streamDeltaErrorMessage(message)));
3469
- return;
3470
- }
3471
- if (messageType === "stop_reason") {
3472
- const stopReason = streamDeltaStopReason(message);
3473
- if (stopReason === "requires_approval") {
3474
- observedRequiresApprovalStop = true;
3475
- return;
3476
- }
3477
- finish("stop_reason", message, stopReason);
3478
- }
3479
- return;
3480
- }
3481
- if (message.type === "update_loop_status") {
3482
- const hadTurnEvidenceBeforeLoopStatus = observedTurnEvidence || observedRequiresApprovalStop;
3483
- if (!hadTurnEvidenceBeforeLoopStatus && (isWaitingOnApprovalLoopStatus(message) || options.allowLoopStatusFallback === true && isWaitingLoopStatus(message))) {
3484
- return;
3485
- }
3486
- for (const runId of message.loop_status.active_run_ids) {
3487
- observedTurnEvidence = true;
3488
- runIds.add(runId);
3489
- }
3490
- if (hadTurnEvidenceBeforeLoopStatus && isWaitingOnApprovalLoopStatus(message)) {
3491
- finish("loop_status_waiting_on_approval", message, "requires_approval");
3492
- return;
3493
- }
3494
- if (options.allowLoopStatusFallback === true && hadTurnEvidenceBeforeLoopStatus && isWaitingLoopStatus(message)) {
3495
- finish("loop_status_waiting_fallback", message, null);
3496
- }
3497
- }
3498
- });
3499
- try {
3500
- this.input(commandWithIds.command);
3501
- } catch (error) {
3502
- fail(error instanceof Error ? error : new Error(String(error)));
3503
- }
3504
- });
3505
- }
3506
- withClientMessageIds(command) {
3507
- if (command.payload.kind !== "create_message") {
3508
- return { command, clientMessageIds: [] };
3509
- }
3510
- const clientMessageIds = [];
3511
- const messages = command.payload.messages.map((message) => {
3512
- if (message.role !== "user")
3513
- return message;
3514
- const existing = message.client_message_id;
3515
- const clientMessageId = typeof existing === "string" && existing.length > 0 ? existing : this.nextRequestId("client-message");
3516
- clientMessageIds.push(clientMessageId);
3517
- return { ...message, client_message_id: clientMessageId };
3390
+ submitInput(command, options = {}) {
3391
+ return this.request({
3392
+ type: "input",
3393
+ request_id: command.request_id ?? this.nextRequestId("input"),
3394
+ ...command
3395
+ }, {
3396
+ ...options,
3397
+ predicate: (message) => message.type === "input_accepted"
3518
3398
  });
3519
- return {
3520
- command: {
3521
- ...command,
3522
- payload: { ...command.payload, messages }
3523
- },
3524
- clientMessageIds
3525
- };
3526
3399
  }
3527
3400
  handleMessage(event, channel) {
3528
3401
  const message = parseProtocolMessage(event);
@@ -6456,6 +6329,73 @@ var models_default = {
6456
6329
  parallel_tool_calls: true
6457
6330
  }
6458
6331
  },
6332
+ {
6333
+ id: "opus-5",
6334
+ handle: "anthropic/claude-opus-5",
6335
+ label: "Opus 5",
6336
+ description: "Opus 5 (high reasoning)",
6337
+ updateArgs: {
6338
+ context_window: 200000,
6339
+ max_output_tokens: 128000,
6340
+ enable_reasoner: true,
6341
+ reasoning_effort: "high",
6342
+ parallel_tool_calls: true
6343
+ }
6344
+ },
6345
+ {
6346
+ id: "opus-5-low",
6347
+ handle: "anthropic/claude-opus-5",
6348
+ label: "Opus 5",
6349
+ description: "Opus 5 (low reasoning)",
6350
+ updateArgs: {
6351
+ context_window: 200000,
6352
+ max_output_tokens: 128000,
6353
+ enable_reasoner: true,
6354
+ reasoning_effort: "low",
6355
+ max_reasoning_tokens: 4000,
6356
+ parallel_tool_calls: true
6357
+ }
6358
+ },
6359
+ {
6360
+ id: "opus-5-medium",
6361
+ handle: "anthropic/claude-opus-5",
6362
+ label: "Opus 5",
6363
+ description: "Opus 5 (med reasoning)",
6364
+ updateArgs: {
6365
+ context_window: 200000,
6366
+ max_output_tokens: 128000,
6367
+ enable_reasoner: true,
6368
+ reasoning_effort: "medium",
6369
+ max_reasoning_tokens: 12000,
6370
+ parallel_tool_calls: true
6371
+ }
6372
+ },
6373
+ {
6374
+ id: "opus-5-xhigh",
6375
+ handle: "anthropic/claude-opus-5",
6376
+ label: "Opus 5",
6377
+ description: "Opus 5 (extra-high reasoning)",
6378
+ updateArgs: {
6379
+ context_window: 200000,
6380
+ max_output_tokens: 128000,
6381
+ enable_reasoner: true,
6382
+ reasoning_effort: "xhigh",
6383
+ parallel_tool_calls: true
6384
+ }
6385
+ },
6386
+ {
6387
+ id: "opus-5-max",
6388
+ handle: "anthropic/claude-opus-5",
6389
+ label: "Opus 5",
6390
+ description: "Opus 5 (max reasoning)",
6391
+ updateArgs: {
6392
+ context_window: 200000,
6393
+ max_output_tokens: 128000,
6394
+ enable_reasoner: true,
6395
+ reasoning_effort: "max",
6396
+ parallel_tool_calls: true
6397
+ }
6398
+ },
6459
6399
  {
6460
6400
  id: "opus",
6461
6401
  handle: "anthropic/claude-opus-4-8",
@@ -6730,7 +6670,7 @@ var models_default = {
6730
6670
  id: "sonnet-5-xhigh",
6731
6671
  handle: "anthropic/claude-sonnet-5",
6732
6672
  label: "Sonnet 5",
6733
- description: "Sonnet 5 (max reasoning)",
6673
+ description: "Sonnet 5 (extra-high reasoning)",
6734
6674
  updateArgs: {
6735
6675
  context_window: 1e6,
6736
6676
  max_output_tokens: 128000,
@@ -6739,6 +6679,19 @@ var models_default = {
6739
6679
  parallel_tool_calls: true
6740
6680
  }
6741
6681
  },
6682
+ {
6683
+ id: "sonnet-5-max",
6684
+ handle: "anthropic/claude-sonnet-5",
6685
+ label: "Sonnet 5",
6686
+ description: "Sonnet 5 (max reasoning)",
6687
+ updateArgs: {
6688
+ context_window: 1e6,
6689
+ max_output_tokens: 128000,
6690
+ reasoning_effort: "max",
6691
+ enable_reasoner: true,
6692
+ parallel_tool_calls: true
6693
+ }
6694
+ },
6742
6695
  {
6743
6696
  id: "sonnet-4.6",
6744
6697
  handle: "anthropic/claude-sonnet-4-6",
@@ -8289,7 +8242,6 @@ var models_default = {
8289
8242
  ]
8290
8243
  };
8291
8244
  var models = models_default.models;
8292
- var MODEL_PRESETS = models;
8293
8245
  function resolveModel(modelIdentifier) {
8294
8246
  const byId = models.find((m) => m.id === modelIdentifier);
8295
8247
  if (byId)
@@ -8517,75 +8469,128 @@ function buildPersonalityMemoryBlocks(personalityId, defaultMemoryBlocks, enviro
8517
8469
  }
8518
8470
  var LETTA_CODE_AGENT_TYPE = "letta_v1_agent";
8519
8471
  var DEFAULT_CREATED_AGENT_BASE_TOOLS = ["web_search", "fetch_webpage"];
8520
- async function buildCreateAgentRequestForPersonality(params) {
8521
- const { personalityId, name, description, model, extraTags } = params;
8522
- const personality = getPersonalityOption(personalityId);
8523
- const modelIdentifier = model ?? personality.defaultModel;
8472
+ function mergeMemoryBlocks(base, overrides) {
8473
+ const blocks = base.map((block) => ({ ...block }));
8474
+ for (const override of overrides ?? []) {
8475
+ const index = blocks.findIndex((block) => block.label === override.label);
8476
+ if (index >= 0) {
8477
+ blocks[index] = { ...override };
8478
+ } else {
8479
+ blocks.push({ ...override });
8480
+ }
8481
+ }
8482
+ return blocks;
8483
+ }
8484
+ async function buildCreateAgentRequest(options = {}) {
8485
+ const personality = options.personalityId ? getPersonalityOption(options.personalityId) : undefined;
8486
+ const modelIdentifier = options.model ?? personality?.defaultModel;
8524
8487
  const modelHandle = modelIdentifier ? resolveModel(modelIdentifier) : getDefaultModel();
8525
8488
  if (!modelHandle) {
8526
8489
  throw new Error(`Unknown model: ${modelIdentifier}`);
8527
8490
  }
8528
- const defaultMemoryBlocks = await getDefaultMemoryBlocks();
8491
+ if (!options.isSubagent && options.enableMemfs !== undefined && options.memoryPromptMode !== undefined && options.enableMemfs !== (options.memoryPromptMode !== "standard")) {
8492
+ throw new Error("enableMemfs and memoryPromptMode must describe the same memory mode");
8493
+ }
8494
+ const enableMemfs = options.isSubagent ? false : options.enableMemfs ?? options.memoryPromptMode !== "standard";
8495
+ const memoryPromptMode = options.isSubagent ? "standard" : options.memoryPromptMode ?? (enableMemfs ? "memfs" : "standard");
8496
+ const personalityTags = options.personalityId ? getPersonalityCreationTags(options.personalityId) : [];
8497
+ const personalityBlocks = options.personalityId ? buildPersonalityMemoryBlocks(options.personalityId, await getDefaultMemoryBlocks()) : [];
8498
+ const memoryBlocks = options.isSubagent ? undefined : options.personalityId || options.memoryBlocks !== undefined ? mergeMemoryBlocks(personalityBlocks, options.memoryBlocks) : undefined;
8499
+ const blockIds = options.isSubagent ? undefined : options.blockIds;
8529
8500
  return {
8530
8501
  agent_type: LETTA_CODE_AGENT_TYPE,
8531
- name: name ?? personality.label,
8532
- description: description ?? personality.description,
8502
+ ...options.name !== undefined || personality ? { name: options.name ?? personality?.label } : {},
8503
+ ...options.description !== undefined || personality ? { description: options.description ?? personality?.description } : {},
8533
8504
  model: modelHandle,
8534
- system: buildSystemPrompt("default", "memfs"),
8535
- memory_blocks: buildPersonalityMemoryBlocks(personalityId, defaultMemoryBlocks),
8505
+ system: options.system ?? buildSystemPrompt("default", memoryPromptMode),
8506
+ ...memoryBlocks !== undefined ? { memory_blocks: memoryBlocks } : {},
8507
+ ...blockIds && blockIds.length > 0 ? { block_ids: blockIds } : {},
8536
8508
  tags: buildCreatedAgentTags({
8537
- enableMemfs: true,
8538
- tags: [
8539
- ...getPersonalityCreationTags(personalityId),
8540
- ...extraTags ?? []
8541
- ]
8509
+ enableMemfs,
8510
+ isSubagent: options.isSubagent,
8511
+ tags: [...personalityTags, ...options.extraTags ?? []]
8542
8512
  }),
8543
- tools: [...DEFAULT_CREATED_AGENT_BASE_TOOLS],
8513
+ tools: [...options.baseTools ?? DEFAULT_CREATED_AGENT_BASE_TOOLS],
8544
8514
  include_base_tools: false,
8545
8515
  include_base_tool_rules: false,
8546
8516
  initial_message_sequence: [],
8547
- parallel_tool_calls: true,
8548
- compaction_settings: { model: DEFAULT_SUMMARIZATION_MODEL }
8517
+ parallel_tool_calls: options.parallelToolCalls ?? true,
8518
+ compaction_settings: {
8519
+ model: options.compactionModel ?? DEFAULT_SUMMARIZATION_MODEL
8520
+ },
8521
+ ...options.embedding !== undefined ? { embedding: options.embedding } : {},
8522
+ ...options.isSubagent ? { hidden: true } : options.hidden !== undefined ? { hidden: options.hidden } : {}
8549
8523
  };
8550
8524
  }
8551
8525
 
8552
8526
  // src/agent-creation.ts
8553
- var DEFAULT_MODEL_ID = "auto";
8554
- var DEFAULT_SUMMARIZATION_MODEL2 = "letta/auto";
8555
- function resolveModel2(modelIdentifier) {
8556
- const preset = MODEL_PRESETS.find((model) => model.id === modelIdentifier || model.handle === modelIdentifier);
8557
- if (preset)
8558
- return preset.handle;
8559
- if (modelIdentifier.includes("/"))
8560
- return modelIdentifier;
8561
- throw new Error(`Unknown model: ${modelIdentifier}`);
8527
+ function isPresetSystemPrompt(value) {
8528
+ return [
8529
+ "default",
8530
+ "letta-claude",
8531
+ "letta-codex",
8532
+ "letta-gemini",
8533
+ "claude",
8534
+ "codex",
8535
+ "gemini"
8536
+ ].includes(value);
8562
8537
  }
8563
- async function buildInitialAgentBody(options) {
8564
- if (options.personality !== undefined) {
8565
- return {
8566
- ...await buildCreateAgentRequestForPersonality({
8567
- personalityId: options.personality,
8568
- ...options.name !== undefined ? { name: options.name } : {},
8569
- ...options.description !== undefined ? { description: options.description } : {},
8570
- ...options.model !== undefined ? { model: options.model } : {},
8571
- ...options.tags !== undefined ? { extraTags: options.tags } : {}
8572
- })
8573
- };
8538
+ function assertCreateAgentOptionsSupported(options) {
8539
+ if (options.allowedTools !== undefined || options.disallowedTools !== undefined) {
8540
+ throw new Error("App-server createAgent() does not yet support allowedTools/disallowedTools.");
8541
+ }
8542
+ if (options.canUseTool !== undefined) {
8543
+ throw new Error("App-server createAgent() does not yet support canUseTool callbacks.");
8544
+ }
8545
+ if (options.systemInfoReminder !== undefined) {
8546
+ throw new Error("App-server createAgent() does not yet support systemInfoReminder overrides.");
8547
+ }
8548
+ if (options.dreaming?.behavior !== undefined) {
8549
+ throw new Error("App-server createAgent() does not yet support dreaming.behavior overrides.");
8574
8550
  }
8575
- return {
8576
- agent_type: LETTA_CODE_AGENT_TYPE,
8577
- ...options.name !== undefined ? { name: options.name } : {},
8578
- ...options.description !== undefined ? { description: options.description } : {},
8579
- model: resolveModel2(options.model ?? DEFAULT_MODEL_ID),
8580
- system: buildSystemPrompt("default", "memfs"),
8581
- tags: buildCreatedAgentTags({
8582
- enableMemfs: true,
8583
- tags: options.tags ?? []
8584
- }),
8585
- initial_message_sequence: [],
8586
- parallel_tool_calls: true,
8587
- compaction_settings: { model: DEFAULT_SUMMARIZATION_MODEL2 }
8588
- };
8551
+ }
8552
+ async function createAgentBody(options) {
8553
+ assertCreateAgentOptionsSupported(options);
8554
+ let system;
8555
+ if (options.systemPrompt !== undefined) {
8556
+ if (typeof options.systemPrompt !== "string" || isPresetSystemPrompt(options.systemPrompt)) {
8557
+ throw new Error("createAgent() does not yet support system prompt presets for this backend.");
8558
+ }
8559
+ system = options.systemPrompt;
8560
+ }
8561
+ const memoryBlocks = [];
8562
+ const blockIds = [];
8563
+ for (const item of options.memory ?? []) {
8564
+ if (typeof item === "string") {
8565
+ throw new Error("App-server createAgent() does not yet support memory preset names.");
8566
+ }
8567
+ if ("blockId" in item) {
8568
+ blockIds.push(item.blockId);
8569
+ } else {
8570
+ memoryBlocks.push({ ...item });
8571
+ }
8572
+ }
8573
+ if (options.persona !== undefined) {
8574
+ memoryBlocks.push({ label: "persona", value: options.persona });
8575
+ }
8576
+ if (options.human !== undefined) {
8577
+ memoryBlocks.push({ label: "human", value: options.human });
8578
+ }
8579
+ const hasMemoryConfiguration = options.memory !== undefined || options.persona !== undefined || options.human !== undefined;
8580
+ return buildCreateAgentRequest({
8581
+ personalityId: options.personality,
8582
+ name: options.name,
8583
+ description: options.description,
8584
+ model: options.model,
8585
+ system,
8586
+ memoryBlocks: hasMemoryConfiguration ? memoryBlocks : undefined,
8587
+ blockIds,
8588
+ extraTags: options.tags,
8589
+ enableMemfs: options.memfs ?? true,
8590
+ baseTools: options.baseTools,
8591
+ embedding: options.embedding,
8592
+ hidden: options.hidden
8593
+ });
8589
8594
  }
8590
8595
 
8591
8596
  // src/interactiveToolPolicy.ts
@@ -8877,7 +8882,7 @@ function firstToolReturn(delta) {
8877
8882
  }
8878
8883
  return;
8879
8884
  }
8880
- function sameRuntime2(message, runtime) {
8885
+ function sameRuntime(message, runtime) {
8881
8886
  const msgRuntime = message.runtime;
8882
8887
  if (msgRuntime) {
8883
8888
  return msgRuntime.agent_id === runtime.agent_id && msgRuntime.conversation_id === runtime.conversation_id;
@@ -8896,10 +8901,10 @@ function streamDeltaRecord(message) {
8896
8901
  const delta = message.delta;
8897
8902
  return delta && typeof delta === "object" && !Array.isArray(delta) ? delta : null;
8898
8903
  }
8899
- function streamDeltaMessageType2(delta) {
8904
+ function streamDeltaMessageType(delta) {
8900
8905
  return typeof delta.message_type === "string" ? delta.message_type : undefined;
8901
8906
  }
8902
- function streamDeltaRunId2(delta) {
8907
+ function streamDeltaRunId(delta) {
8903
8908
  return typeof delta.run_id === "string" ? delta.run_id : undefined;
8904
8909
  }
8905
8910
  function streamDeltaOtid(delta) {
@@ -8908,7 +8913,7 @@ function streamDeltaOtid(delta) {
8908
8913
  function streamDeltaSeqId(delta) {
8909
8914
  return typeof delta.seq_id === "number" ? delta.seq_id : undefined;
8910
8915
  }
8911
- function streamDeltaStopReason2(delta) {
8916
+ function streamDeltaStopReason(delta) {
8912
8917
  return typeof delta.stop_reason === "string" ? delta.stop_reason : undefined;
8913
8918
  }
8914
8919
  function loopStatusRecord(message) {
@@ -9131,7 +9136,7 @@ class RemoteTurnCoordinator {
9131
9136
  this.activeTurn.abortRequested = true;
9132
9137
  }
9133
9138
  handleProtocolMessage(message, runtime) {
9134
- if (!sameRuntime2(message, runtime))
9139
+ if (!sameRuntime(message, runtime))
9135
9140
  return;
9136
9141
  const statusRecord = deviceStatusRecord(message);
9137
9142
  if (statusRecord) {
@@ -9158,7 +9163,7 @@ class RemoteTurnCoordinator {
9158
9163
  const active = this.activateNextTurnFromProtocol();
9159
9164
  if (active) {
9160
9165
  active.observedTurnEvidence = true;
9161
- const runId = streamDeltaRunId2(delta);
9166
+ const runId = streamDeltaRunId(delta);
9162
9167
  if (runId)
9163
9168
  active.runIds.add(runId);
9164
9169
  }
@@ -9177,6 +9182,24 @@ class RemoteTurnCoordinator {
9177
9182
  this.streamResolvers.push(resolve);
9178
9183
  });
9179
9184
  }
9185
+ closeWithError(detail) {
9186
+ if (this.closed)
9187
+ return;
9188
+ const active = this.activeTurn;
9189
+ if (active) {
9190
+ this.failTurn(active, detail);
9191
+ } else {
9192
+ this.enqueue({
9193
+ type: "error",
9194
+ message: detail,
9195
+ errorCode: "error",
9196
+ stopReason: "error",
9197
+ errorDetail: detail,
9198
+ recoverable: false
9199
+ });
9200
+ }
9201
+ this.close();
9202
+ }
9180
9203
  close() {
9181
9204
  if (this.closed)
9182
9205
  return;
@@ -9294,9 +9317,9 @@ class RemoteTurnCoordinator {
9294
9317
  const active = this.activeTurn;
9295
9318
  if (!active)
9296
9319
  return;
9297
- const messageType = streamDeltaMessageType2(delta);
9320
+ const messageType = streamDeltaMessageType(delta);
9298
9321
  if (messageType === "stop_reason") {
9299
- const stopReason = streamDeltaStopReason2(delta) ?? null;
9322
+ const stopReason = streamDeltaStopReason(delta) ?? null;
9300
9323
  if (stopReason === "requires_approval") {
9301
9324
  active.observedRequiresApprovalStop = true;
9302
9325
  return;
@@ -9490,6 +9513,7 @@ class RemoteClientSessionCore {
9490
9513
  requestTimeoutMs;
9491
9514
  initializePromise = null;
9492
9515
  removeMessageHandler = null;
9516
+ detachTransportDisconnect = null;
9493
9517
  turns;
9494
9518
  toolNames;
9495
9519
  deviceStatusListeners = new Set;
@@ -9564,6 +9588,8 @@ class RemoteClientSessionCore {
9564
9588
  cleanupFailedInitialize() {
9565
9589
  this.removeMessageHandler?.();
9566
9590
  this.removeMessageHandler = null;
9591
+ this.detachTransportDisconnect?.();
9592
+ this.detachTransportDisconnect = null;
9567
9593
  this.controller?.close();
9568
9594
  this.controller = null;
9569
9595
  this.onCoreClose();
@@ -9594,7 +9620,7 @@ class RemoteClientSessionCore {
9594
9620
  throw error;
9595
9621
  }
9596
9622
  }
9597
- async runTurn(message, _options = {}) {
9623
+ async sendAndWaitForResult(message) {
9598
9624
  if (this.turns.hasInFlightTurn()) {
9599
9625
  throw new Error(`A turn is already in flight for this ${this.label} session. Use send() and stream() to let the listener queue messages.`);
9600
9626
  }
@@ -9851,6 +9877,8 @@ class RemoteClientSessionCore {
9851
9877
  this.closed = true;
9852
9878
  this.removeMessageHandler?.();
9853
9879
  this.removeMessageHandler = null;
9880
+ this.detachTransportDisconnect?.();
9881
+ this.detachTransportDisconnect = null;
9854
9882
  this.turns.close();
9855
9883
  for (const cancel of [...this.deviceStatusRefreshCancels]) {
9856
9884
  cancel(new Error(`Session closed while waiting for ${this.label} device status`));
@@ -9911,6 +9939,15 @@ class RemoteClientSessionCore {
9911
9939
  }, { predicate: (message) => message.type === "update_toolset_response" });
9912
9940
  ensureSuccess(response, "Failed to update toolset");
9913
9941
  }
9942
+ watchTransportDisconnect(client) {
9943
+ this.detachTransportDisconnect?.();
9944
+ this.detachTransportDisconnect = client.onDisconnect(() => {
9945
+ if (this.closed)
9946
+ return;
9947
+ this.turns.closeWithError(`The ${this.label} connection closed unexpectedly; resume the conversation to continue.`);
9948
+ this.close();
9949
+ });
9950
+ }
9914
9951
  async afterRuntimeInitialized() {}
9915
9952
  async beforeTurn() {}
9916
9953
  onCoreClose() {}
@@ -10032,111 +10069,6 @@ function agentToolNames(agent) {
10032
10069
  return typeof name === "string" && name.length > 0 ? [name] : [];
10033
10070
  });
10034
10071
  }
10035
- function isPresetSystemPrompt(value) {
10036
- return [
10037
- "default",
10038
- "letta-claude",
10039
- "letta-codex",
10040
- "letta-gemini",
10041
- "claude",
10042
- "codex",
10043
- "gemini"
10044
- ].includes(value);
10045
- }
10046
- function assertRemoteCreateAgentOptionsSupported(options) {
10047
- if (options.allowedTools !== undefined || options.disallowedTools !== undefined) {
10048
- throw new Error("App-server createAgent() does not yet support allowedTools/disallowedTools.");
10049
- }
10050
- if (options.canUseTool !== undefined) {
10051
- throw new Error("App-server createAgent() does not yet support canUseTool callbacks.");
10052
- }
10053
- if (options.systemInfoReminder !== undefined) {
10054
- throw new Error("App-server createAgent() does not yet support systemInfoReminder overrides.");
10055
- }
10056
- if (options.dreaming?.behavior !== undefined) {
10057
- throw new Error("App-server createAgent() does not yet support dreaming.behavior overrides.");
10058
- }
10059
- }
10060
- function normalizeMemoryBlock(block) {
10061
- const normalized = { ...block };
10062
- if (normalized.value === undefined && typeof normalized.content === "string") {
10063
- normalized.value = normalized.content;
10064
- }
10065
- return normalized;
10066
- }
10067
- function upsertMemoryBlock(blocks, block) {
10068
- const label = block.label;
10069
- if (typeof label === "string") {
10070
- const existingIndex = blocks.findIndex((candidate) => candidate.label === label);
10071
- if (existingIndex >= 0) {
10072
- blocks[existingIndex] = block;
10073
- return;
10074
- }
10075
- }
10076
- blocks.push(block);
10077
- }
10078
- async function createAgentBody(options, settings = {}) {
10079
- assertRemoteCreateAgentOptionsSupported(options);
10080
- const includeOriginTag = settings.includeSdkOriginTag ?? true;
10081
- const body = await buildInitialAgentBody(options);
10082
- if (Array.isArray(body.tags)) {
10083
- body.tags = body.tags.filter((tag) => (includeOriginTag || tag !== LETTA_CODE_ORIGIN_TAG) && (options.memfs !== false || tag !== GIT_MEMORY_ENABLED_TAG));
10084
- }
10085
- if (options.embedding !== undefined)
10086
- body.embedding = options.embedding;
10087
- if (options.hidden !== undefined)
10088
- body.hidden = options.hidden;
10089
- if (options.baseTools === undefined) {
10090
- delete body.tools;
10091
- delete body.include_base_tools;
10092
- delete body.include_base_tool_rules;
10093
- } else {
10094
- body.tools = options.baseTools;
10095
- body.include_base_tools = false;
10096
- body.include_base_tool_rules = false;
10097
- }
10098
- if (options.systemPrompt === undefined) {
10099
- if (options.memfs === false) {
10100
- body.system = buildSystemPrompt("default", "standard");
10101
- }
10102
- } else {
10103
- if (typeof options.systemPrompt === "string") {
10104
- if (isPresetSystemPrompt(options.systemPrompt)) {
10105
- throw new Error("createAgent() does not yet support system prompt presets for this backend.");
10106
- }
10107
- body.system = options.systemPrompt;
10108
- } else {
10109
- throw new Error("createAgent() does not yet support system prompt preset objects for this backend.");
10110
- }
10111
- }
10112
- const hasMemoryConfiguration = Array.isArray(body.memory_blocks) || options.memory !== undefined || options.persona !== undefined || options.human !== undefined;
10113
- const memoryBlocks = Array.isArray(body.memory_blocks) ? body.memory_blocks.filter((block) => block !== null && typeof block === "object").map((block) => ({ ...block })) : [];
10114
- const blockIds = [];
10115
- for (const item of options.memory ?? []) {
10116
- if (typeof item === "string") {
10117
- throw new Error("App-server createAgent() does not yet support memory preset names.");
10118
- }
10119
- if ("blockId" in item) {
10120
- blockIds.push(item.blockId);
10121
- } else {
10122
- upsertMemoryBlock(memoryBlocks, normalizeMemoryBlock(item));
10123
- }
10124
- }
10125
- if (options.persona !== undefined) {
10126
- upsertMemoryBlock(memoryBlocks, {
10127
- label: "persona",
10128
- value: options.persona
10129
- });
10130
- }
10131
- if (options.human !== undefined) {
10132
- upsertMemoryBlock(memoryBlocks, { label: "human", value: options.human });
10133
- }
10134
- if (hasMemoryConfiguration)
10135
- body.memory_blocks = memoryBlocks;
10136
- if (blockIds.length > 0)
10137
- body.block_ids = blockIds;
10138
- return body;
10139
- }
10140
10072
  function externalToolGroups(tools) {
10141
10073
  if (!tools || tools.length === 0)
10142
10074
  return;
@@ -10515,6 +10447,7 @@ class AppServerSession extends RemoteClientSessionCore {
10515
10447
  if (!response.success || !response.runtime) {
10516
10448
  throw new Error(response.error ?? "Failed to start app-server runtime");
10517
10449
  }
10450
+ this.watchTransportDisconnect(client);
10518
10451
  const tools = agentToolNames(response.agent);
10519
10452
  const skillSources = options.skillSources;
10520
10453
  const clientToolset = "toolset" in options ? options.toolset : undefined;
@@ -10597,9 +10530,7 @@ class AppServerSession extends RemoteClientSessionCore {
10597
10530
  command.external_tools = groups;
10598
10531
  if (this.mode.kind === "create-agent") {
10599
10532
  command.create_agent = {
10600
- body: await createAgentBody(this.mode.options, {
10601
- includeSdkOriginTag: this.remoteOptions.includeSdkOriginTag
10602
- }),
10533
+ body: await createAgentBody(this.mode.options),
10603
10534
  pin_global: this.remoteOptions.pinGlobalAgent ?? this.mode.options.hidden !== true,
10604
10535
  ...this.mode.options.memfs === false ? { memfs: false } : {}
10605
10536
  };
@@ -10670,6 +10601,16 @@ function cloudModelEntry(raw) {
10670
10601
  function isNotFound(error) {
10671
10602
  return error instanceof APIError && error.status === 404;
10672
10603
  }
10604
+ function toOrderRelativeCursors(query) {
10605
+ if ((query.order ?? "desc") !== "desc")
10606
+ return query;
10607
+ const { before, after, ...rest } = query;
10608
+ return {
10609
+ ...rest,
10610
+ ...after != null ? { before: after } : {},
10611
+ ...before != null ? { after: before } : {}
10612
+ };
10613
+ }
10673
10614
 
10674
10615
  class CloudManagementTransport {
10675
10616
  client;
@@ -10745,7 +10686,7 @@ class CloudManagementTransport {
10745
10686
  return this.client.conversations.update(conversationId, body);
10746
10687
  }
10747
10688
  async listConversationMessages(conversationId, query) {
10748
- const page = await this.client.conversations.messages.list(conversationId, query);
10689
+ const page = await this.client.conversations.messages.list(conversationId, toOrderRelativeCursors(query));
10749
10690
  return { messages: page.items };
10750
10691
  }
10751
10692
  }
@@ -11284,6 +11225,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
11284
11225
  if (!response.success || !response.runtime) {
11285
11226
  throw new Error(response.error ?? "Failed to start Cloud status runtime");
11286
11227
  }
11228
+ this.watchTransportDisconnect(client);
11287
11229
  const tools = agentToolNames(response.agent);
11288
11230
  const skillSources = options.skillSources;
11289
11231
  const clientToolset = "toolset" in options ? options.toolset : undefined;
@@ -11829,14 +11771,6 @@ function getBlockLabels(memory) {
11829
11771
  return null;
11830
11772
  }).filter((label) => label !== null);
11831
11773
  }
11832
- function validateApprovalRecoveryOptions(options) {
11833
- if (options.maxApprovalRecoveryAttempts !== undefined && (!Number.isInteger(options.maxApprovalRecoveryAttempts) || options.maxApprovalRecoveryAttempts < 0)) {
11834
- throw new Error("Invalid maxApprovalRecoveryAttempts. Expected a non-negative integer.");
11835
- }
11836
- if (options.approvalRecoveryTimeoutMs !== undefined && (!Number.isInteger(options.approvalRecoveryTimeoutMs) || options.approvalRecoveryTimeoutMs <= 0)) {
11837
- throw new Error("Invalid approvalRecoveryTimeoutMs. Expected a positive integer.");
11838
- }
11839
- }
11840
11774
  function validateRemovedSessionOptions(options) {
11841
11775
  const removedOptions = options;
11842
11776
  if (removedOptions.systemPrompt !== undefined) {
@@ -11949,7 +11883,6 @@ function validateCreateSessionOptions(options) {
11949
11883
  validateMcpServers(options.mcpServers);
11950
11884
  validateReasoningEffort(options.reasoningEffort);
11951
11885
  validateDreamingOptions(options.dreaming);
11952
- validateApprovalRecoveryOptions(options);
11953
11886
  validateRemovedSessionOptions(options);
11954
11887
  }
11955
11888
  function validateCreateAgentOptions(options) {
@@ -12157,7 +12090,7 @@ class LettaAgentClientBase {
12157
12090
  async prompt(message, agentId, options = {}) {
12158
12091
  const session = this.createSession(agentId, options);
12159
12092
  try {
12160
- return await session.runTurn(message);
12093
+ return await session.sendAndWaitForResult(message);
12161
12094
  } finally {
12162
12095
  session.close();
12163
12096
  }
@@ -29498,7 +29431,7 @@ class StreamableHTTPClientTransport {
29498
29431
  }
29499
29432
  var DEFAULT_CLIENT_INFO = {
29500
29433
  name: "letta-code",
29501
- version: "0.30.0"
29434
+ version: "0.30.5"
29502
29435
  };
29503
29436
  async function connectMcpServer(config2, options = {}) {
29504
29437
  let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
@@ -29926,7 +29859,7 @@ function resumeSession(id, options = {}) {
29926
29859
  async function prompt(message, agentId, options = {}) {
29927
29860
  const session = createSession(agentId, options);
29928
29861
  try {
29929
- return await session.runTurn(message);
29862
+ return await session.sendAndWaitForResult(message);
29930
29863
  } finally {
29931
29864
  session.close();
29932
29865
  }
@@ -29996,4 +29929,4 @@ export {
29996
29929
  CloudManagedSandboxExpiredError
29997
29930
  };
29998
29931
 
29999
- //# debugId=CE7ED5A95338695C64756E2164756E21
29932
+ //# debugId=9E741E442389C4A864756E2164756E21