@letta-ai/letta-agent-sdk 0.5.0 → 0.5.1
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/README.md +2 -7
- package/dist/client-entry.js +60 -19
- package/dist/client-entry.js.map +4 -4
- package/dist/cloud-session.d.ts +2 -0
- package/dist/cloud-session.d.ts.map +1 -1
- package/dist/index.js +60 -19
- package/dist/index.js.map +4 -4
- package/dist/remote-session-protocol.d.ts.map +1 -1
- package/dist/types.d.ts +10 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cloud-session.ts +104 -20
- package/src/remote-session-protocol.ts +4 -0
- package/src/types.ts +10 -2
package/README.md
CHANGED
|
@@ -44,12 +44,6 @@ for await (const message of session.stream()) {
|
|
|
44
44
|
}
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Assistant and reasoning messages are incremental text fragments. Reconcile
|
|
48
|
-
fragments by `type` and `otid` when `otid` is available; `uuid` is a legacy
|
|
49
|
-
transport identifier and is not a portable lineage key. After reconnecting,
|
|
50
|
-
use `(runId, seqId)` to suppress replayed fragments. Sequence IDs are scoped to
|
|
51
|
-
their run and must not be compared across runs.
|
|
52
|
-
|
|
53
47
|
An agent is the persistent entity with memory. A conversation is a thread on that agent. A session is the active connection used to send messages, stream events, execute tools, and handle approvals.
|
|
54
48
|
|
|
55
49
|
- `createSession(agentId)` starts a new conversation.
|
|
@@ -86,7 +80,8 @@ approvals when a mobile or web client returns to the foreground:
|
|
|
86
80
|
```ts
|
|
87
81
|
const status = await session.getDeviceStatus();
|
|
88
82
|
// status.permissionMode, status.workingDirectory, status.isOnline,
|
|
89
|
-
// status.isProcessing, status.
|
|
83
|
+
// status.isProcessing, status.memoryDirectory,
|
|
84
|
+
// status.pendingControlRequests, status.raw
|
|
90
85
|
|
|
91
86
|
const unsubscribe = session.onDeviceStatus((status) => {
|
|
92
87
|
// Called for every device-status update pushed by the runtime.
|
package/dist/client-entry.js
CHANGED
|
@@ -5987,6 +5987,7 @@ function toSessionDeviceStatus(status) {
|
|
|
5987
5987
|
isProcessing: status.is_processing,
|
|
5988
5988
|
permissionMode,
|
|
5989
5989
|
workingDirectory: status.current_working_directory,
|
|
5990
|
+
memoryDirectory: typeof status.memory_directory === "string" ? status.memory_directory : null,
|
|
5990
5991
|
pendingControlRequests: pendingControlRequests(status),
|
|
5991
5992
|
raw: { ...status }
|
|
5992
5993
|
};
|
|
@@ -8298,6 +8299,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8298
8299
|
sandboxRefreshInFlight = null;
|
|
8299
8300
|
sandboxLifecycleClosing = false;
|
|
8300
8301
|
attachedRepositoryIds = new Set;
|
|
8302
|
+
repositoryIdsRequiringCleanupRecompile = new Set;
|
|
8301
8303
|
cloudMode;
|
|
8302
8304
|
constructor(cloudOptions, mode) {
|
|
8303
8305
|
super(mode, {
|
|
@@ -8311,7 +8313,10 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8311
8313
|
}
|
|
8312
8314
|
async initializeRuntimeController() {
|
|
8313
8315
|
const resolved = await this.resolveRuntime();
|
|
8314
|
-
const connection = await this.resolveConnectionForRuntime(resolved.runtime)
|
|
8316
|
+
const connection = await this.resolveConnectionForRuntime(resolved.runtime).catch(async (error) => {
|
|
8317
|
+
await this.cleanupSessionRepositories(resolved.runtime.agent_id, resolved.runtime.conversation_id);
|
|
8318
|
+
throw error;
|
|
8319
|
+
});
|
|
8315
8320
|
this.connectionId = connection.connectionId;
|
|
8316
8321
|
const apiKey = getCloudApiKey2(this.cloudOptions);
|
|
8317
8322
|
const url = buildCloudStatusWebSocketUrl({
|
|
@@ -8366,7 +8371,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8366
8371
|
this.removeControlRequestHandler = null;
|
|
8367
8372
|
client.close();
|
|
8368
8373
|
await this.cleanupManagedSandbox();
|
|
8369
|
-
await this.cleanupSessionRepositories(resolved.runtime.agent_id);
|
|
8374
|
+
await this.cleanupSessionRepositories(resolved.runtime.agent_id, resolved.runtime.conversation_id);
|
|
8370
8375
|
throw error;
|
|
8371
8376
|
}
|
|
8372
8377
|
}
|
|
@@ -8417,8 +8422,9 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8417
8422
|
this.removeControlRequestHandler?.();
|
|
8418
8423
|
this.removeControlRequestHandler = null;
|
|
8419
8424
|
this.cleanupManagedSandbox();
|
|
8420
|
-
if (this.runtime?.agent_id)
|
|
8421
|
-
this.cleanupSessionRepositories(this.runtime.agent_id);
|
|
8425
|
+
if (this.runtime?.agent_id) {
|
|
8426
|
+
this.cleanupSessionRepositories(this.runtime.agent_id, this.runtime.conversation_id);
|
|
8427
|
+
}
|
|
8422
8428
|
}
|
|
8423
8429
|
async resolveRuntime() {
|
|
8424
8430
|
let agentId = this.cloudMode.agentId;
|
|
@@ -8433,22 +8439,30 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8433
8439
|
if (!agentId) {
|
|
8434
8440
|
throw new Error("Letta Cloud createSession()/resumeSession() requires an agent id or conversation id.");
|
|
8435
8441
|
}
|
|
8436
|
-
await this.attachSessionRepositories(agentId);
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8442
|
+
const shouldRecompileRepositories = await this.attachSessionRepositories(agentId);
|
|
8443
|
+
try {
|
|
8444
|
+
if (this.cloudMode.newConversation) {
|
|
8445
|
+
const conversation = await this.createConversation(agentId);
|
|
8446
|
+
conversationId = conversation.id;
|
|
8447
|
+
} else if (this.cloudMode.defaultConversation) {
|
|
8448
|
+
conversationId = "default";
|
|
8449
|
+
}
|
|
8450
|
+
if (!conversationId) {
|
|
8451
|
+
throw new Error("Letta Cloud createSession()/resumeSession() requires an agent id or conversation id.");
|
|
8452
|
+
}
|
|
8453
|
+
if (shouldRecompileRepositories) {
|
|
8454
|
+
await this.recompileSystemPrompt(agentId, conversationId);
|
|
8455
|
+
}
|
|
8456
|
+
return { runtime: { agent_id: agentId, conversation_id: conversationId } };
|
|
8457
|
+
} catch (error) {
|
|
8458
|
+
await this.cleanupSessionRepositories(agentId, conversationId);
|
|
8459
|
+
throw error;
|
|
8445
8460
|
}
|
|
8446
|
-
return { runtime: { agent_id: agentId, conversation_id: conversationId } };
|
|
8447
8461
|
}
|
|
8448
8462
|
async attachSessionRepositories(agentId) {
|
|
8449
8463
|
const resources = this.repositoryResources();
|
|
8450
8464
|
if (resources.length === 0)
|
|
8451
|
-
return;
|
|
8465
|
+
return false;
|
|
8452
8466
|
const existing = await this.listAgentRepositories(agentId);
|
|
8453
8467
|
const existingIds = new Set(existing.map((repository) => repository.id));
|
|
8454
8468
|
try {
|
|
@@ -8464,15 +8478,42 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8464
8478
|
await this.cleanupSessionRepositories(agentId);
|
|
8465
8479
|
throw error;
|
|
8466
8480
|
}
|
|
8481
|
+
const shouldRecompile = resources.some((resource) => resource.recompile !== false);
|
|
8482
|
+
this.repositoryIdsRequiringCleanupRecompile = new Set(resources.filter((resource) => resource.recompile !== false && this.attachedRepositoryIds.has(resource.repositoryId)).map((resource) => resource.repositoryId));
|
|
8483
|
+
return shouldRecompile;
|
|
8467
8484
|
}
|
|
8468
|
-
async cleanupSessionRepositories(agentId) {
|
|
8485
|
+
async cleanupSessionRepositories(agentId, conversationId) {
|
|
8469
8486
|
const repositoryIds = [...this.attachedRepositoryIds];
|
|
8487
|
+
const repositoryIdsRequiringRecompile = this.repositoryIdsRequiringCleanupRecompile;
|
|
8470
8488
|
this.attachedRepositoryIds.clear();
|
|
8471
|
-
|
|
8489
|
+
this.repositoryIdsRequiringCleanupRecompile = new Set;
|
|
8490
|
+
const recompileAfterDetach = await Promise.all(repositoryIds.map(async (repositoryId) => {
|
|
8472
8491
|
try {
|
|
8473
8492
|
await this.unlinkAgentRepository(agentId, repositoryId);
|
|
8474
|
-
|
|
8493
|
+
return repositoryIdsRequiringRecompile.has(repositoryId);
|
|
8494
|
+
} catch {
|
|
8495
|
+
return false;
|
|
8496
|
+
}
|
|
8475
8497
|
}));
|
|
8498
|
+
if (recompileAfterDetach.some(Boolean)) {
|
|
8499
|
+
try {
|
|
8500
|
+
await this.recompileSystemPrompt(agentId, conversationId);
|
|
8501
|
+
} catch {}
|
|
8502
|
+
}
|
|
8503
|
+
}
|
|
8504
|
+
async recompileSystemPrompt(agentId, conversationId) {
|
|
8505
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8506
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8507
|
+
const usesAgentPrompt = !conversationId || conversationId === "default";
|
|
8508
|
+
const path = usesAgentPrompt ? `/v1/agents/${encodeURIComponent(agentId)}/recompile` : `/v1/conversations/${encodeURIComponent(conversationId)}/recompile`;
|
|
8509
|
+
const url = `${baseUrl}${path}`;
|
|
8510
|
+
const response = await fetchImpl(url, {
|
|
8511
|
+
method: "POST",
|
|
8512
|
+
headers: cloudHeaders2(this.cloudOptions),
|
|
8513
|
+
body: JSON.stringify(usesAgentPrompt ? {} : { agent_id: agentId })
|
|
8514
|
+
});
|
|
8515
|
+
const body = await parseJsonResponse3(response);
|
|
8516
|
+
assertOkResponse2(response, body, "Cloud recompile system prompt", url);
|
|
8476
8517
|
}
|
|
8477
8518
|
repositoryResources() {
|
|
8478
8519
|
const resources = this.cloudMode.options.resources ?? [];
|
|
@@ -9388,4 +9429,4 @@ export {
|
|
|
9388
9429
|
CloudManagedSandboxExpiredError
|
|
9389
9430
|
};
|
|
9390
9431
|
|
|
9391
|
-
//# debugId=
|
|
9432
|
+
//# debugId=C4A49597208F4A6464756E2164756E21
|