@letta-ai/letta-agent-sdk 0.5.0 → 0.5.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.
- package/AGENTS.md +35 -0
- package/README.md +22 -10
- package/dist/agent-repositories.d.ts +15 -0
- package/dist/agent-repositories.d.ts.map +1 -0
- package/dist/app-server-management.d.ts +10 -7
- package/dist/app-server-management.d.ts.map +1 -1
- package/dist/app-server-models.d.ts +4 -0
- package/dist/app-server-models.d.ts.map +1 -0
- package/dist/app-server-session.d.ts +3 -3
- package/dist/app-server-session.d.ts.map +1 -1
- package/dist/client-base.d.ts +5 -0
- package/dist/client-base.d.ts.map +1 -1
- package/dist/client-entry.js +3386 -639
- package/dist/client-entry.js.map +85 -13
- package/dist/cloud-client.d.ts +7 -0
- package/dist/cloud-client.d.ts.map +1 -0
- package/dist/cloud-management.d.ts +21 -18
- package/dist/cloud-management.d.ts.map +1 -1
- package/dist/cloud-session.d.ts +7 -5
- 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 +3400 -653
- package/dist/index.js.map +86 -14
- package/dist/management-types.d.ts +85 -64
- package/dist/management-types.d.ts.map +1 -1
- package/dist/management.d.ts +11 -9
- package/dist/management.d.ts.map +1 -1
- package/dist/remote-session-protocol.d.ts +1 -1
- package/dist/remote-session-protocol.d.ts.map +1 -1
- package/dist/remote.d.ts +4 -5
- package/dist/remote.d.ts.map +1 -1
- package/dist/repositories.d.ts +3 -2
- package/dist/repositories.d.ts.map +1 -1
- package/dist/types.d.ts +22 -34
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/agent-repositories.ts +159 -0
- package/src/app-server-management.ts +56 -116
- package/src/app-server-models.ts +20 -0
- package/src/app-server-session.ts +71 -146
- package/src/client-base.ts +72 -20
- package/src/cloud-client.ts +46 -0
- package/src/cloud-management.ts +128 -275
- package/src/cloud-session.ts +168 -267
- package/src/index.ts +6 -0
- package/src/management-types.ts +107 -64
- package/src/management.ts +46 -39
- package/src/remote-session-protocol.ts +6 -2
- package/src/remote.ts +18 -63
- package/src/repositories.ts +26 -99
- package/src/types.ts +22 -35
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AgentRepositoriesClient,
|
|
3
|
+
AgentRepository,
|
|
4
|
+
AgentRepositoryRecompileTarget,
|
|
5
|
+
AttachAgentRepositoryOptions,
|
|
6
|
+
DetachAgentRepositoryOptions,
|
|
7
|
+
AgentRepositoryPermissions,
|
|
8
|
+
} from "./management-types.js";
|
|
9
|
+
|
|
10
|
+
const DEFAULT_VISIBILITY_TIMEOUT_MS = 10_000;
|
|
11
|
+
const DEFAULT_VISIBILITY_POLL_INTERVAL_MS = 100;
|
|
12
|
+
|
|
13
|
+
export interface AgentRepositoriesTransport {
|
|
14
|
+
listAgentRepositories(agentId: string): Promise<AgentRepository[]>;
|
|
15
|
+
attachAgentRepository(
|
|
16
|
+
agentId: string,
|
|
17
|
+
repositoryId: string,
|
|
18
|
+
permissions: AgentRepositoryPermissions | undefined,
|
|
19
|
+
): Promise<AgentRepository>;
|
|
20
|
+
detachAgentRepository(
|
|
21
|
+
agentId: string,
|
|
22
|
+
repositoryId: string,
|
|
23
|
+
): Promise<void>;
|
|
24
|
+
recompileAgentSystemPrompt(agentId: string): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type TransportProvider = () => AgentRepositoriesTransport;
|
|
28
|
+
|
|
29
|
+
type VisibilityOptions = {
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
pollIntervalMs?: number;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function assertNonEmptyId(value: string, name: string): void {
|
|
35
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
36
|
+
throw new Error(`Invalid ${name}. Expected a non-empty string.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function assertPermissions(
|
|
41
|
+
permissions: AgentRepositoryPermissions | undefined,
|
|
42
|
+
): void {
|
|
43
|
+
if (
|
|
44
|
+
permissions !== undefined &&
|
|
45
|
+
permissions !== "read" &&
|
|
46
|
+
permissions !== "read_write"
|
|
47
|
+
) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Invalid repository permissions '${String(permissions)}'. Expected "read" or "read_write".`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function assertRecompileTarget(
|
|
55
|
+
recompile: AgentRepositoryRecompileTarget | undefined,
|
|
56
|
+
): void {
|
|
57
|
+
if (recompile !== undefined && recompile !== "default" && recompile !== false) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`Invalid repository recompile target '${String(recompile)}'. Expected "default" or false.`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function sleep(ms: number): Promise<void> {
|
|
65
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function waitForRepositoryState(
|
|
69
|
+
transport: AgentRepositoriesTransport,
|
|
70
|
+
agentId: string,
|
|
71
|
+
repositoryId: string,
|
|
72
|
+
attached: boolean,
|
|
73
|
+
permissions: AgentRepositoryPermissions | undefined,
|
|
74
|
+
options: VisibilityOptions,
|
|
75
|
+
): Promise<void> {
|
|
76
|
+
const deadline = Date.now() +
|
|
77
|
+
(options.timeoutMs ?? DEFAULT_VISIBILITY_TIMEOUT_MS);
|
|
78
|
+
while (true) {
|
|
79
|
+
const repositories = await transport.listAgentRepositories(agentId);
|
|
80
|
+
const repository = repositories.find(
|
|
81
|
+
(repository) => repository.id === repositoryId,
|
|
82
|
+
);
|
|
83
|
+
const isDesiredState = attached
|
|
84
|
+
? repository !== undefined && repository.permissions === permissions
|
|
85
|
+
: repository === undefined;
|
|
86
|
+
if (isDesiredState) return;
|
|
87
|
+
if (Date.now() >= deadline) {
|
|
88
|
+
const action = attached ? "attach" : "detach";
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Cloud ${action} agent repository did not become visible for ${agentId}: ${repositoryId}`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
await sleep(
|
|
94
|
+
options.pollIntervalMs ?? DEFAULT_VISIBILITY_POLL_INTERVAL_MS,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function createAgentRepositoriesClient(
|
|
100
|
+
transportProvider: TransportProvider,
|
|
101
|
+
visibilityOptions: VisibilityOptions = {},
|
|
102
|
+
): AgentRepositoriesClient {
|
|
103
|
+
return {
|
|
104
|
+
list: async (agentId) => {
|
|
105
|
+
assertNonEmptyId(agentId, "agent id");
|
|
106
|
+
return transportProvider().listAgentRepositories(agentId);
|
|
107
|
+
},
|
|
108
|
+
attach: async (
|
|
109
|
+
agentId: string,
|
|
110
|
+
repositoryId: string,
|
|
111
|
+
options: AttachAgentRepositoryOptions = {},
|
|
112
|
+
) => {
|
|
113
|
+
assertNonEmptyId(agentId, "agent id");
|
|
114
|
+
assertNonEmptyId(repositoryId, "repository id");
|
|
115
|
+
assertPermissions(options.permissions);
|
|
116
|
+
assertRecompileTarget(options.recompile);
|
|
117
|
+
const transport = transportProvider();
|
|
118
|
+
const repository = await transport.attachAgentRepository(
|
|
119
|
+
agentId,
|
|
120
|
+
repositoryId,
|
|
121
|
+
options.permissions,
|
|
122
|
+
);
|
|
123
|
+
await waitForRepositoryState(
|
|
124
|
+
transport,
|
|
125
|
+
agentId,
|
|
126
|
+
repositoryId,
|
|
127
|
+
true,
|
|
128
|
+
repository.permissions,
|
|
129
|
+
visibilityOptions,
|
|
130
|
+
);
|
|
131
|
+
if (options.recompile !== false) {
|
|
132
|
+
await transport.recompileAgentSystemPrompt(agentId);
|
|
133
|
+
}
|
|
134
|
+
return repository;
|
|
135
|
+
},
|
|
136
|
+
detach: async (
|
|
137
|
+
agentId: string,
|
|
138
|
+
repositoryId: string,
|
|
139
|
+
options: DetachAgentRepositoryOptions = {},
|
|
140
|
+
) => {
|
|
141
|
+
assertNonEmptyId(agentId, "agent id");
|
|
142
|
+
assertNonEmptyId(repositoryId, "repository id");
|
|
143
|
+
assertRecompileTarget(options.recompile);
|
|
144
|
+
const transport = transportProvider();
|
|
145
|
+
await transport.detachAgentRepository(agentId, repositoryId);
|
|
146
|
+
await waitForRepositoryState(
|
|
147
|
+
transport,
|
|
148
|
+
agentId,
|
|
149
|
+
repositoryId,
|
|
150
|
+
false,
|
|
151
|
+
undefined,
|
|
152
|
+
visibilityOptions,
|
|
153
|
+
);
|
|
154
|
+
if (options.recompile !== false) {
|
|
155
|
+
await transport.recompileAgentSystemPrompt(agentId);
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
@@ -1,59 +1,43 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createAppServerClient,
|
|
3
3
|
type AppServerClient,
|
|
4
|
-
type
|
|
4
|
+
type AppServerRawResponse,
|
|
5
5
|
type AppServerSocketConstructor,
|
|
6
6
|
} from "@letta-ai/letta-code/app-server-client";
|
|
7
7
|
import type {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
AgentDeleteResponseMessage,
|
|
9
|
+
AgentListResponseMessage,
|
|
10
|
+
AgentRetrieveResponseMessage,
|
|
11
|
+
AgentUpdateResponseMessage,
|
|
12
|
+
ConversationCreateResponseMessage,
|
|
13
|
+
ConversationListResponseMessage,
|
|
14
|
+
ConversationMessagesListResponseMessage,
|
|
15
|
+
ConversationRetrieveResponseMessage,
|
|
16
|
+
ConversationUpdateResponseMessage,
|
|
17
|
+
ListModelsResponseMessage,
|
|
18
|
+
} from "@letta-ai/letta-code/app-server-protocol";
|
|
19
|
+
import type {
|
|
20
|
+
AgentListParams,
|
|
21
|
+
AgentUpdateParams,
|
|
22
|
+
} from "@letta-ai/letta-client/resources/agents/agents";
|
|
23
|
+
import type {
|
|
24
|
+
ConversationCreateParams,
|
|
25
|
+
ConversationListParams,
|
|
26
|
+
ConversationUpdateParams,
|
|
27
|
+
} from "@letta-ai/letta-client/resources/conversations/conversations";
|
|
28
|
+
import type { MessageListParams } from "@letta-ai/letta-client/resources/conversations/messages";
|
|
29
|
+
import { normalizeAppServerModels } from "./app-server-models.js";
|
|
30
|
+
import type { ManagementTransport } from "./management.js";
|
|
11
31
|
import { applyUniqueRequestIds } from "./request-ids.js";
|
|
12
32
|
import type {
|
|
13
33
|
ConversationMessagesResult,
|
|
14
34
|
LettaAgent,
|
|
15
35
|
LettaConversation,
|
|
16
36
|
} from "./management-types.js";
|
|
17
|
-
import type {
|
|
18
|
-
LettaCodeModelEntry,
|
|
19
|
-
LettaCodeRemoteClientOptions,
|
|
20
|
-
ListModelsResult,
|
|
21
|
-
} from "./types.js";
|
|
37
|
+
import type { LettaCodeRemoteClientOptions, ListModelsResult } from "./types.js";
|
|
22
38
|
|
|
23
39
|
type OwnedConnection = { url: string; close(): void };
|
|
24
40
|
|
|
25
|
-
type ManagementResponse = {
|
|
26
|
-
type: string;
|
|
27
|
-
success: boolean;
|
|
28
|
-
error?: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
type AgentListResponse = ManagementResponse & {
|
|
32
|
-
agents: LettaAgent[];
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
type AgentResponse = ManagementResponse & {
|
|
36
|
-
agent: LettaAgent | null;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
type ConversationListResponse = ManagementResponse & {
|
|
40
|
-
conversations: LettaConversation[];
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
type ConversationResponse = ManagementResponse & {
|
|
44
|
-
conversation: LettaConversation | null;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
type ConversationMessagesResponse = ManagementResponse & {
|
|
48
|
-
messages: Record<string, unknown>[];
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
type ListModelsResponse = ManagementResponse & {
|
|
52
|
-
entries?: unknown;
|
|
53
|
-
available_handles?: unknown;
|
|
54
|
-
byok_provider_aliases?: unknown;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
41
|
export type AppServerManagementOptions =
|
|
58
42
|
Partial<LettaCodeRemoteClientOptions> & {
|
|
59
43
|
url?: string;
|
|
@@ -77,39 +61,6 @@ function ensureResponse<T>(
|
|
|
77
61
|
return value;
|
|
78
62
|
}
|
|
79
63
|
|
|
80
|
-
function modelEntries(value: unknown): LettaCodeModelEntry[] {
|
|
81
|
-
if (!Array.isArray(value)) return [];
|
|
82
|
-
return value.flatMap((entry) => {
|
|
83
|
-
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
|
|
84
|
-
const record = entry as Record<string, unknown>;
|
|
85
|
-
if (
|
|
86
|
-
typeof record.id !== "string" ||
|
|
87
|
-
typeof record.handle !== "string" ||
|
|
88
|
-
typeof record.label !== "string" ||
|
|
89
|
-
typeof record.description !== "string"
|
|
90
|
-
) {
|
|
91
|
-
return [];
|
|
92
|
-
}
|
|
93
|
-
return [{
|
|
94
|
-
...record,
|
|
95
|
-
id: record.id,
|
|
96
|
-
handle: record.handle,
|
|
97
|
-
label: record.label,
|
|
98
|
-
description: record.description,
|
|
99
|
-
}];
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function stringRecord(value: unknown): Record<string, string> | undefined {
|
|
104
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
const entries = Object.entries(value as Record<string, unknown>).filter(
|
|
108
|
-
(entry): entry is [string, string] => typeof entry[1] === "string",
|
|
109
|
-
);
|
|
110
|
-
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
64
|
/**
|
|
114
65
|
* Management transport that speaks the app-server control protocol.
|
|
115
66
|
*
|
|
@@ -125,8 +76,8 @@ export class AppServerManagementTransport
|
|
|
125
76
|
|
|
126
77
|
constructor(private readonly options: AppServerManagementOptions) {}
|
|
127
78
|
|
|
128
|
-
async listAgents(query:
|
|
129
|
-
const response = await this.request<
|
|
79
|
+
async listAgents(query: AgentListParams): Promise<LettaAgent[]> {
|
|
80
|
+
const response = await this.request<AgentListResponseMessage>(
|
|
130
81
|
"agent_list",
|
|
131
82
|
{ query },
|
|
132
83
|
"agent_list_response",
|
|
@@ -138,7 +89,7 @@ export class AppServerManagementTransport
|
|
|
138
89
|
}
|
|
139
90
|
|
|
140
91
|
async retrieveAgent(agentId: string): Promise<LettaAgent> {
|
|
141
|
-
const response = await this.request<
|
|
92
|
+
const response = await this.request<AgentRetrieveResponseMessage>(
|
|
142
93
|
"agent_retrieve",
|
|
143
94
|
{ agent_id: agentId },
|
|
144
95
|
"agent_retrieve_response",
|
|
@@ -152,9 +103,9 @@ export class AppServerManagementTransport
|
|
|
152
103
|
|
|
153
104
|
async updateAgent(
|
|
154
105
|
agentId: string,
|
|
155
|
-
body:
|
|
106
|
+
body: AgentUpdateParams,
|
|
156
107
|
): Promise<LettaAgent> {
|
|
157
|
-
const response = await this.request<
|
|
108
|
+
const response = await this.request<AgentUpdateResponseMessage>(
|
|
158
109
|
"agent_update",
|
|
159
110
|
{ agent_id: agentId, body },
|
|
160
111
|
"agent_update_response",
|
|
@@ -167,7 +118,7 @@ export class AppServerManagementTransport
|
|
|
167
118
|
}
|
|
168
119
|
|
|
169
120
|
async deleteAgent(agentId: string): Promise<void> {
|
|
170
|
-
const response = await this.request<
|
|
121
|
+
const response = await this.request<AgentDeleteResponseMessage>(
|
|
171
122
|
"agent_delete",
|
|
172
123
|
{ agent_id: agentId },
|
|
173
124
|
"agent_delete_response",
|
|
@@ -180,33 +131,18 @@ export class AppServerManagementTransport
|
|
|
180
131
|
async listModels(): Promise<ListModelsResult> {
|
|
181
132
|
// A bare list_models command (no runtime scope) is answered on the
|
|
182
133
|
// control channel, so no session or conversation is required.
|
|
183
|
-
const response = await this.request<
|
|
134
|
+
const response = await this.request<ListModelsResponseMessage>(
|
|
184
135
|
"list_models",
|
|
185
136
|
{},
|
|
186
137
|
"list_models_response",
|
|
187
138
|
);
|
|
188
|
-
|
|
189
|
-
throw new Error(response.error ?? "Failed to list models.");
|
|
190
|
-
}
|
|
191
|
-
const result: ListModelsResult = {
|
|
192
|
-
entries: modelEntries(response.entries),
|
|
193
|
-
};
|
|
194
|
-
if (response.available_handles === null) {
|
|
195
|
-
result.availableHandles = null;
|
|
196
|
-
} else if (Array.isArray(response.available_handles)) {
|
|
197
|
-
result.availableHandles = response.available_handles.filter(
|
|
198
|
-
(handle): handle is string => typeof handle === "string",
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
const aliases = stringRecord(response.byok_provider_aliases);
|
|
202
|
-
if (aliases) result.byokProviderAliases = aliases;
|
|
203
|
-
return result;
|
|
139
|
+
return normalizeAppServerModels(response);
|
|
204
140
|
}
|
|
205
141
|
|
|
206
142
|
async listConversations(
|
|
207
|
-
query:
|
|
143
|
+
query: ConversationListParams,
|
|
208
144
|
): Promise<LettaConversation[]> {
|
|
209
|
-
const response = await this.request<
|
|
145
|
+
const response = await this.request<ConversationListResponseMessage>(
|
|
210
146
|
"conversation_list",
|
|
211
147
|
{ query },
|
|
212
148
|
"conversation_list_response",
|
|
@@ -220,7 +156,7 @@ export class AppServerManagementTransport
|
|
|
220
156
|
async retrieveConversation(
|
|
221
157
|
conversationId: string,
|
|
222
158
|
): Promise<LettaConversation> {
|
|
223
|
-
const response = await this.request<
|
|
159
|
+
const response = await this.request<ConversationRetrieveResponseMessage>(
|
|
224
160
|
"conversation_retrieve",
|
|
225
161
|
{ conversation_id: conversationId },
|
|
226
162
|
"conversation_retrieve_response",
|
|
@@ -233,9 +169,9 @@ export class AppServerManagementTransport
|
|
|
233
169
|
}
|
|
234
170
|
|
|
235
171
|
async createConversation(
|
|
236
|
-
body:
|
|
172
|
+
body: ConversationCreateParams,
|
|
237
173
|
): Promise<LettaConversation> {
|
|
238
|
-
const response = await this.request<
|
|
174
|
+
const response = await this.request<ConversationCreateResponseMessage>(
|
|
239
175
|
"conversation_create",
|
|
240
176
|
{ body },
|
|
241
177
|
"conversation_create_response",
|
|
@@ -249,9 +185,9 @@ export class AppServerManagementTransport
|
|
|
249
185
|
|
|
250
186
|
async updateConversation(
|
|
251
187
|
conversationId: string,
|
|
252
|
-
body:
|
|
188
|
+
body: ConversationUpdateParams,
|
|
253
189
|
): Promise<LettaConversation> {
|
|
254
|
-
const response = await this.request<
|
|
190
|
+
const response = await this.request<ConversationUpdateResponseMessage>(
|
|
255
191
|
"conversation_update",
|
|
256
192
|
{ conversation_id: conversationId, body },
|
|
257
193
|
"conversation_update_response",
|
|
@@ -265,10 +201,10 @@ export class AppServerManagementTransport
|
|
|
265
201
|
|
|
266
202
|
async listConversationMessages(
|
|
267
203
|
conversationId: string,
|
|
268
|
-
query:
|
|
204
|
+
query: MessageListParams,
|
|
269
205
|
): Promise<ConversationMessagesResult> {
|
|
270
206
|
const response =
|
|
271
|
-
await this.request<
|
|
207
|
+
await this.request<ConversationMessagesListResponseMessage>(
|
|
272
208
|
"conversation_messages_list",
|
|
273
209
|
{ conversation_id: conversationId, query },
|
|
274
210
|
"conversation_messages_list_response",
|
|
@@ -294,16 +230,20 @@ export class AppServerManagementTransport
|
|
|
294
230
|
// counter, while connection identity keeps this pool independent from
|
|
295
231
|
// session clients using the same app-server.
|
|
296
232
|
const { client } = await this.acquireConnection();
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
message
|
|
305
|
-
|
|
306
|
-
|
|
233
|
+
return client.requestRaw<TResponse & AppServerRawResponse>(
|
|
234
|
+
{
|
|
235
|
+
type,
|
|
236
|
+
request_id: client.nextRequestId(type),
|
|
237
|
+
...body,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
predicate: (message): message is TResponse & AppServerRawResponse =>
|
|
241
|
+
message !== null &&
|
|
242
|
+
typeof message === "object" &&
|
|
243
|
+
"type" in message &&
|
|
244
|
+
message.type === responseType,
|
|
245
|
+
},
|
|
246
|
+
);
|
|
307
247
|
}
|
|
308
248
|
|
|
309
249
|
private acquireConnection(): Promise<ActiveConnection> {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ListModelsResponseMessage } from "@letta-ai/letta-code/app-server-protocol";
|
|
2
|
+
import type { ListModelsResult } from "./types.js";
|
|
3
|
+
|
|
4
|
+
export function normalizeAppServerModels(
|
|
5
|
+
response: ListModelsResponseMessage,
|
|
6
|
+
): ListModelsResult {
|
|
7
|
+
if (!response.success) {
|
|
8
|
+
throw new Error(response.error ?? "listModels failed");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
entries: response.entries,
|
|
13
|
+
...(response.available_handles !== undefined
|
|
14
|
+
? { availableHandles: response.available_handles }
|
|
15
|
+
: {}),
|
|
16
|
+
...(response.byok_provider_aliases !== undefined
|
|
17
|
+
? { byokProviderAliases: response.byok_provider_aliases }
|
|
18
|
+
: {}),
|
|
19
|
+
};
|
|
20
|
+
}
|