@letta-ai/letta-agent-sdk 0.3.2 → 0.3.3
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/AGENTS.md +47 -0
- package/README.md +17 -0
- package/dist/client-entry.js +800 -732
- package/dist/client-entry.js.map +8 -5
- package/dist/cloud-sandbox.d.ts +33 -0
- package/dist/cloud-sandbox.d.ts.map +1 -0
- package/dist/cloud-session.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +799 -732
- package/dist/index.js.map +9 -6
- package/dist/remote-client-session-core.d.ts +6 -93
- package/dist/remote-client-session-core.d.ts.map +1 -1
- package/dist/remote-session-protocol.d.ts +130 -0
- package/dist/remote-session-protocol.d.ts.map +1 -0
- package/dist/remote-turn-coordinator.d.ts +49 -0
- package/dist/remote-turn-coordinator.d.ts.map +1 -0
- package/dist/types.d.ts +2 -20
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -2
- package/src/app-server-management.ts +641 -0
- package/src/app-server-session.ts +948 -0
- package/src/cli-resolver.ts +46 -0
- package/src/client-base.ts +482 -0
- package/src/client-entry.ts +31 -0
- package/src/client.ts +138 -0
- package/src/cloud-management.ts +360 -0
- package/src/cloud-sandbox.ts +117 -0
- package/src/cloud-session.ts +1313 -0
- package/src/index.ts +440 -0
- package/src/interactiveToolPolicy.ts +62 -0
- package/src/local-app-server-session.ts +39 -0
- package/src/local-app-server.ts +137 -0
- package/src/management-types.ts +133 -0
- package/src/management.ts +206 -0
- package/src/protocol.ts +249 -0
- package/src/remote-client-session-core.ts +786 -0
- package/src/remote-session-protocol.ts +660 -0
- package/src/remote-turn-coordinator.ts +505 -0
- package/src/remote.ts +177 -0
- package/src/repositories.ts +340 -0
- package/src/request-ids.ts +33 -0
- package/src/session.ts +1638 -0
- package/src/stream-events.ts +88 -0
- package/src/tool-helpers.ts +147 -0
- package/src/transport.ts +484 -0
- package/src/types.ts +1328 -0
- package/src/validation.ts +223 -0
- package/src/websocket.ts +22 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK Validation
|
|
3
|
+
*
|
|
4
|
+
* Validates user-provided options before spawning the CLI.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
CreateSessionOptions,
|
|
9
|
+
CreateAgentOptions,
|
|
10
|
+
MemoryItem,
|
|
11
|
+
CreateBlock,
|
|
12
|
+
SystemPromptPreset,
|
|
13
|
+
SkillSource,
|
|
14
|
+
DreamingOptions,
|
|
15
|
+
} from "./types.js";
|
|
16
|
+
|
|
17
|
+
const VALID_SKILL_SOURCES: SkillSource[] = [
|
|
18
|
+
"bundled",
|
|
19
|
+
"global",
|
|
20
|
+
"agent",
|
|
21
|
+
"project",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const VALID_REASONING_EFFORTS = [
|
|
25
|
+
"none",
|
|
26
|
+
"minimal",
|
|
27
|
+
"low",
|
|
28
|
+
"medium",
|
|
29
|
+
"high",
|
|
30
|
+
"xhigh",
|
|
31
|
+
] as const;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Extract block labels from memory items.
|
|
35
|
+
*/
|
|
36
|
+
function getBlockLabels(memory: MemoryItem[]): string[] {
|
|
37
|
+
return memory
|
|
38
|
+
.map((item) => {
|
|
39
|
+
if (typeof item === "string") return item; // preset name
|
|
40
|
+
if ("label" in item) return (item as CreateBlock).label; // CreateBlock
|
|
41
|
+
return null; // blockId - no label to check
|
|
42
|
+
})
|
|
43
|
+
.filter((label): label is string => label !== null);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function validateApprovalRecoveryOptions(options: CreateSessionOptions): void {
|
|
47
|
+
if (
|
|
48
|
+
options.maxApprovalRecoveryAttempts !== undefined &&
|
|
49
|
+
(!Number.isInteger(options.maxApprovalRecoveryAttempts) ||
|
|
50
|
+
options.maxApprovalRecoveryAttempts < 0)
|
|
51
|
+
) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
"Invalid maxApprovalRecoveryAttempts. Expected a non-negative integer."
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (
|
|
58
|
+
options.approvalRecoveryTimeoutMs !== undefined &&
|
|
59
|
+
(!Number.isInteger(options.approvalRecoveryTimeoutMs) ||
|
|
60
|
+
options.approvalRecoveryTimeoutMs <= 0)
|
|
61
|
+
) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
"Invalid approvalRecoveryTimeoutMs. Expected a positive integer."
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function validateRemovedSessionOptions(options: CreateSessionOptions): void {
|
|
69
|
+
if ((options as { memfsStartup?: unknown }).memfsStartup !== undefined) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"memfsStartup is not supported by the SDK.",
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate systemPrompt preset value.
|
|
78
|
+
*/
|
|
79
|
+
function validateSystemPromptPreset(preset: string): void {
|
|
80
|
+
const validPresets = [
|
|
81
|
+
"default",
|
|
82
|
+
"letta-claude",
|
|
83
|
+
"letta-codex",
|
|
84
|
+
"letta-gemini",
|
|
85
|
+
"claude",
|
|
86
|
+
"codex",
|
|
87
|
+
"gemini",
|
|
88
|
+
];
|
|
89
|
+
if (!validPresets.includes(preset)) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Invalid system prompt preset '${preset}'. ` +
|
|
92
|
+
`Valid presets: ${validPresets.join(", ")}`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function validateSkillSources(sources: SkillSource[] | undefined): void {
|
|
98
|
+
if (sources === undefined) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const source of sources) {
|
|
103
|
+
if (!VALID_SKILL_SOURCES.includes(source)) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Invalid skill source '${source}'. Valid values: ${VALID_SKILL_SOURCES.join(", ")}`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function validateDreamingOptions(dreaming: DreamingOptions | undefined): void {
|
|
112
|
+
if (dreaming === undefined) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (
|
|
117
|
+
dreaming.trigger !== undefined &&
|
|
118
|
+
!["off", "step-count", "compaction-event"].includes(dreaming.trigger)
|
|
119
|
+
) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`Invalid dreaming.trigger '${String(dreaming.trigger)}'. Valid values: off, step-count, compaction-event`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (
|
|
126
|
+
dreaming.behavior !== undefined &&
|
|
127
|
+
!["reminder", "auto-launch"].includes(dreaming.behavior)
|
|
128
|
+
) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Invalid dreaming.behavior '${String(dreaming.behavior)}'. Valid values: reminder, auto-launch`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (
|
|
135
|
+
dreaming.stepCount !== undefined &&
|
|
136
|
+
(!Number.isInteger(dreaming.stepCount) || dreaming.stepCount <= 0)
|
|
137
|
+
) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
"Invalid dreaming.stepCount. Expected a positive integer."
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function validateReasoningEffort(value: unknown): void {
|
|
145
|
+
if (value === undefined) return;
|
|
146
|
+
if (
|
|
147
|
+
typeof value !== "string" ||
|
|
148
|
+
!VALID_REASONING_EFFORTS.includes(value as (typeof VALID_REASONING_EFFORTS)[number])
|
|
149
|
+
) {
|
|
150
|
+
throw new Error(
|
|
151
|
+
`Invalid reasoningEffort '${String(value)}'. Valid values: ${VALID_REASONING_EFFORTS.join(", ")}`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Validate CreateSessionOptions (used by createSession and resumeSession).
|
|
158
|
+
*/
|
|
159
|
+
export function validateCreateSessionOptions(options: CreateSessionOptions): void {
|
|
160
|
+
// Validate systemPrompt preset if provided
|
|
161
|
+
if (options.systemPrompt !== undefined) {
|
|
162
|
+
validateSystemPromptPreset(options.systemPrompt);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
validateSkillSources(options.skillSources);
|
|
166
|
+
validateReasoningEffort(options.reasoningEffort);
|
|
167
|
+
validateDreamingOptions(options.dreaming);
|
|
168
|
+
validateApprovalRecoveryOptions(options);
|
|
169
|
+
validateRemovedSessionOptions(options);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Validate CreateAgentOptions (used by createAgent).
|
|
174
|
+
*/
|
|
175
|
+
export function validateCreateAgentOptions(options: CreateAgentOptions): void {
|
|
176
|
+
// Validate memory/persona consistency
|
|
177
|
+
if (options.memory !== undefined) {
|
|
178
|
+
const blockLabels = getBlockLabels(options.memory);
|
|
179
|
+
|
|
180
|
+
if (options.persona !== undefined && !blockLabels.includes("persona")) {
|
|
181
|
+
throw new Error(
|
|
182
|
+
"Cannot set 'persona' value - block not included in 'memory'. " +
|
|
183
|
+
"Either add 'persona' to memory array or remove the persona option."
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (options.human !== undefined && !blockLabels.includes("human")) {
|
|
188
|
+
throw new Error(
|
|
189
|
+
"Cannot set 'human' value - block not included in 'memory'. " +
|
|
190
|
+
"Either add 'human' to memory array or remove the human option."
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Validate systemPrompt preset if provided as preset object
|
|
196
|
+
if (
|
|
197
|
+
options.systemPrompt !== undefined &&
|
|
198
|
+
typeof options.systemPrompt === "object"
|
|
199
|
+
) {
|
|
200
|
+
validateSystemPromptPreset(options.systemPrompt.preset);
|
|
201
|
+
} else if (
|
|
202
|
+
options.systemPrompt !== undefined &&
|
|
203
|
+
typeof options.systemPrompt === "string"
|
|
204
|
+
) {
|
|
205
|
+
// Check if it's a preset name (if so, validate it)
|
|
206
|
+
const validPresets = [
|
|
207
|
+
"default",
|
|
208
|
+
"letta-claude",
|
|
209
|
+
"letta-codex",
|
|
210
|
+
"letta-gemini",
|
|
211
|
+
"claude",
|
|
212
|
+
"codex",
|
|
213
|
+
"gemini",
|
|
214
|
+
] as const;
|
|
215
|
+
if (validPresets.includes(options.systemPrompt as SystemPromptPreset)) {
|
|
216
|
+
validateSystemPromptPreset(options.systemPrompt);
|
|
217
|
+
}
|
|
218
|
+
// If not a preset, it's a custom string - no validation needed
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
validateSkillSources(options.skillSources);
|
|
222
|
+
validateDreamingOptions(options.dreaming);
|
|
223
|
+
}
|
package/src/websocket.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
LettaCodeReactNativeSocketConstructor,
|
|
3
|
+
LettaCodeSocketConstructor,
|
|
4
|
+
LettaCodeSocketOptions,
|
|
5
|
+
} from "./types.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Adapt React Native's three-argument WebSocket constructor to the SDK's
|
|
9
|
+
* Node-compatible constructor shape. This is only needed when a remote
|
|
10
|
+
* app-server authenticates its websocket upgrade with headers. Cloud clients
|
|
11
|
+
* should prefer `webSocketAuth: "query"`.
|
|
12
|
+
*/
|
|
13
|
+
export function createReactNativeWebSocketConstructor(
|
|
14
|
+
WebSocket: LettaCodeReactNativeSocketConstructor,
|
|
15
|
+
): LettaCodeSocketConstructor {
|
|
16
|
+
class ReactNativeWebSocketAdapter {
|
|
17
|
+
constructor(url: string, options?: LettaCodeSocketOptions) {
|
|
18
|
+
return new WebSocket(url, undefined, options);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return ReactNativeWebSocketAdapter as unknown as LettaCodeSocketConstructor;
|
|
22
|
+
}
|