+1
-1
deno.json
+1
-1
deno.json
···
11
11
"@js-temporal/polyfill": "npm:@js-temporal/polyfill",
12
12
"@atproto/api": "npm:@atproto/api",
13
13
"@atproto/lexicon": "npm:@atproto/lexicon",
14
-
"@letta-ai/letta-client": "npm:@letta-ai/letta-client",
14
+
"@letta-ai/letta-client": "npm:@letta-ai/letta-client@1.0.0",
15
15
"@voyager/autonomy-lexicon": "jsr:@voyager/autonomy-lexicon@^0.1.1"
16
16
}
17
17
}
+4
-253
deno.lock
+4
-253
deno.lock
···
8
8
"npm:@atproto/api@*": "0.17.2",
9
9
"npm:@atproto/lexicon@*": "0.5.1",
10
10
"npm:@js-temporal/polyfill@*": "0.5.1",
11
-
"npm:@letta-ai/letta-client@*": "0.0.68664"
11
+
"npm:@letta-ai/letta-client@1.0.0": "1.0.0"
12
12
},
13
13
"jsr": {
14
14
"@std/assert@1.0.15": {
···
76
76
"jsbi"
77
77
]
78
78
},
79
-
"@letta-ai/letta-client@0.0.68664": {
80
-
"integrity": "sha512-/0g8dV3IIX0WfnOUDY1EEgnhj/747m73zhTmbLhldEMjCk/RzKyjvUeZbHiukiGoCf/u1nxRgcRUn66MKMYB2A==",
81
-
"dependencies": [
82
-
"form-data",
83
-
"form-data-encoder",
84
-
"formdata-node",
85
-
"node-fetch",
86
-
"qs",
87
-
"readable-stream",
88
-
"url-join"
89
-
]
90
-
},
91
-
"abort-controller@3.0.0": {
92
-
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
93
-
"dependencies": [
94
-
"event-target-shim"
95
-
]
96
-
},
97
-
"asynckit@0.4.0": {
98
-
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
79
+
"@letta-ai/letta-client@1.0.0": {
80
+
"integrity": "sha512-owR/gcLVFlv89CtJsb1m4xvYJcApooyEvrzqWLgf6bnfJuog65YXPUdwZIsA2YBk9a3u+l3wvYsDuk0uj5PCtA=="
99
81
},
100
82
"await-lock@2.2.2": {
101
83
"integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw=="
102
84
},
103
-
"base64-js@1.5.1": {
104
-
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
105
-
},
106
-
"buffer@6.0.3": {
107
-
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
108
-
"dependencies": [
109
-
"base64-js",
110
-
"ieee754"
111
-
]
112
-
},
113
-
"call-bind-apply-helpers@1.0.2": {
114
-
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
115
-
"dependencies": [
116
-
"es-errors",
117
-
"function-bind"
118
-
]
119
-
},
120
-
"call-bound@1.0.4": {
121
-
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
122
-
"dependencies": [
123
-
"call-bind-apply-helpers",
124
-
"get-intrinsic"
125
-
]
126
-
},
127
-
"combined-stream@1.0.8": {
128
-
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
129
-
"dependencies": [
130
-
"delayed-stream"
131
-
]
132
-
},
133
-
"delayed-stream@1.0.0": {
134
-
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
135
-
},
136
-
"dunder-proto@1.0.1": {
137
-
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
138
-
"dependencies": [
139
-
"call-bind-apply-helpers",
140
-
"es-errors",
141
-
"gopd"
142
-
]
143
-
},
144
-
"es-define-property@1.0.1": {
145
-
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
146
-
},
147
-
"es-errors@1.3.0": {
148
-
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
149
-
},
150
-
"es-object-atoms@1.1.1": {
151
-
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
152
-
"dependencies": [
153
-
"es-errors"
154
-
]
155
-
},
156
-
"es-set-tostringtag@2.1.0": {
157
-
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
158
-
"dependencies": [
159
-
"es-errors",
160
-
"get-intrinsic",
161
-
"has-tostringtag",
162
-
"hasown"
163
-
]
164
-
},
165
-
"event-target-shim@5.0.1": {
166
-
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
167
-
},
168
-
"events@3.3.0": {
169
-
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
170
-
},
171
-
"form-data-encoder@4.1.0": {
172
-
"integrity": "sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw=="
173
-
},
174
-
"form-data@4.0.4": {
175
-
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
176
-
"dependencies": [
177
-
"asynckit",
178
-
"combined-stream",
179
-
"es-set-tostringtag",
180
-
"hasown",
181
-
"mime-types"
182
-
]
183
-
},
184
-
"formdata-node@6.0.3": {
185
-
"integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg=="
186
-
},
187
-
"function-bind@1.1.2": {
188
-
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
189
-
},
190
-
"get-intrinsic@1.3.0": {
191
-
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
192
-
"dependencies": [
193
-
"call-bind-apply-helpers",
194
-
"es-define-property",
195
-
"es-errors",
196
-
"es-object-atoms",
197
-
"function-bind",
198
-
"get-proto",
199
-
"gopd",
200
-
"has-symbols",
201
-
"hasown",
202
-
"math-intrinsics"
203
-
]
204
-
},
205
-
"get-proto@1.0.1": {
206
-
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
207
-
"dependencies": [
208
-
"dunder-proto",
209
-
"es-object-atoms"
210
-
]
211
-
},
212
-
"gopd@1.2.0": {
213
-
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
214
-
},
215
85
"graphemer@1.4.0": {
216
86
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
217
87
},
218
-
"has-symbols@1.1.0": {
219
-
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="
220
-
},
221
-
"has-tostringtag@1.0.2": {
222
-
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
223
-
"dependencies": [
224
-
"has-symbols"
225
-
]
226
-
},
227
-
"hasown@2.0.2": {
228
-
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
229
-
"dependencies": [
230
-
"function-bind"
231
-
]
232
-
},
233
-
"ieee754@1.2.1": {
234
-
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
235
-
},
236
88
"iso-datestring-validator@2.2.2": {
237
89
"integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA=="
238
90
},
239
91
"jsbi@4.3.2": {
240
92
"integrity": "sha512-9fqMSQbhJykSeii05nxKl4m6Eqn2P6rOlYiS+C5Dr/HPIU/7yZxu5qzbs40tgaFORiw2Amd0mirjxatXYMkIew=="
241
93
},
242
-
"math-intrinsics@1.1.0": {
243
-
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
244
-
},
245
-
"mime-db@1.52.0": {
246
-
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
247
-
},
248
-
"mime-types@2.1.35": {
249
-
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
250
-
"dependencies": [
251
-
"mime-db"
252
-
]
253
-
},
254
94
"multiformats@9.9.0": {
255
95
"integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
256
96
},
257
-
"node-fetch@2.7.0": {
258
-
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
259
-
"dependencies": [
260
-
"whatwg-url"
261
-
]
262
-
},
263
-
"object-inspect@1.13.4": {
264
-
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="
265
-
},
266
-
"process@0.11.10": {
267
-
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
268
-
},
269
-
"qs@6.14.0": {
270
-
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
271
-
"dependencies": [
272
-
"side-channel"
273
-
]
274
-
},
275
-
"readable-stream@4.7.0": {
276
-
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
277
-
"dependencies": [
278
-
"abort-controller",
279
-
"buffer",
280
-
"events",
281
-
"process",
282
-
"string_decoder"
283
-
]
284
-
},
285
-
"safe-buffer@5.2.1": {
286
-
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
287
-
},
288
-
"side-channel-list@1.0.0": {
289
-
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
290
-
"dependencies": [
291
-
"es-errors",
292
-
"object-inspect"
293
-
]
294
-
},
295
-
"side-channel-map@1.0.1": {
296
-
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
297
-
"dependencies": [
298
-
"call-bound",
299
-
"es-errors",
300
-
"get-intrinsic",
301
-
"object-inspect"
302
-
]
303
-
},
304
-
"side-channel-weakmap@1.0.2": {
305
-
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
306
-
"dependencies": [
307
-
"call-bound",
308
-
"es-errors",
309
-
"get-intrinsic",
310
-
"object-inspect",
311
-
"side-channel-map"
312
-
]
313
-
},
314
-
"side-channel@1.1.0": {
315
-
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
316
-
"dependencies": [
317
-
"es-errors",
318
-
"object-inspect",
319
-
"side-channel-list",
320
-
"side-channel-map",
321
-
"side-channel-weakmap"
322
-
]
323
-
},
324
-
"string_decoder@1.3.0": {
325
-
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
326
-
"dependencies": [
327
-
"safe-buffer"
328
-
]
329
-
},
330
97
"tlds@1.260.0": {
331
98
"integrity": "sha512-78+28EWBhCEE7qlyaHA9OR3IPvbCLiDh3Ckla593TksfFc9vfTsgvH7eS+dr3o9qr31gwGbogcI16yN91PoRjQ==",
332
99
"bin": true
333
100
},
334
-
"tr46@0.0.3": {
335
-
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
336
-
},
337
101
"uint8arrays@3.0.0": {
338
102
"integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==",
339
103
"dependencies": [
340
104
"multiformats"
341
105
]
342
106
},
343
-
"url-join@4.0.1": {
344
-
"integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
345
-
},
346
-
"webidl-conversions@3.0.1": {
347
-
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
348
-
},
349
-
"whatwg-url@5.0.0": {
350
-
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
351
-
"dependencies": [
352
-
"tr46",
353
-
"webidl-conversions"
354
-
]
355
-
},
356
107
"zod@3.25.76": {
357
108
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="
358
109
}
···
365
116
"npm:@atproto/api@*",
366
117
"npm:@atproto/lexicon@*",
367
118
"npm:@js-temporal/polyfill@*",
368
-
"npm:@letta-ai/letta-client@*"
119
+
"npm:@letta-ai/letta-client@1.0.0"
369
120
]
370
121
}
371
122
}
+20
-16
mount.ts
+20
-16
mount.ts
···
139
139
*/
140
140
export async function mount(): Promise<void> {
141
141
const agentId = Deno.env.get("LETTA_AGENT_ID");
142
-
const agentName = Deno.env.get("LETTA_PROJECT_NAME");
142
+
const agentName = Deno.env.get("LETTA_PROJECT_ID");
143
143
144
144
if (!agentId) {
145
145
console.error(
···
156
156
console.log(`Agent retrieved: ${agent.name}`);
157
157
158
158
// Get all existing blocks for this agent
159
-
const existingBlocks = await client.agents.blocks.list(agentId);
159
+
const existingBlocksPage = await client.agents.blocks.list(agentId);
160
+
const existingBlocks = existingBlocksPage.items;
160
161
console.log(`Agent has ${existingBlocks.length} existing memory blocks`);
161
162
162
163
// Build dynamic memory blocks array based on configuration
···
216
217
);
217
218
} else {
218
219
console.log(`Updating existing block: ${blockConfig.label}`);
219
-
await client.blocks.modify(existingBlock.id, {
220
+
await client.blocks.update(existingBlock.id, {
220
221
value: blockConfig.value,
221
222
description: blockConfig.description,
222
223
limit: blockConfig.limit,
···
236
237
237
238
// Attach the block to the agent
238
239
if (newBlock.id) {
239
-
await client.agents.blocks.attach(agentId, newBlock.id);
240
+
await client.agents.blocks.attach(newBlock.id, { agent_id: agentId });
240
241
console.log(`✓ Attached block: ${blockConfig.label}`);
241
242
} else {
242
243
throw new Error(`Failed to create block: ${blockConfig.label}`);
···
259
260
}
260
261
261
262
// Update agent with tool environment variables
262
-
await client.agents.modify(agentId, {
263
-
toolExecEnvironmentVariables: {
263
+
await client.agents.update(agentId, {
264
+
secrets: {
264
265
BSKY_USERNAME: bskyUsername || "",
265
266
BSKY_APP_PASSWORD: bskyAppPassword || "",
266
267
BSKY_SERVICE_URL: bskyServiceUrl || "https://bsky.social",
···
286
287
}
287
288
288
289
// Get currently attached tools
289
-
const attachedTools = await client.agents.tools.list(agentId);
290
+
const attachedToolsPage = await client.agents.tools.list(agentId);
291
+
const attachedTools = attachedToolsPage.items;
290
292
const attachedToolNames = attachedTools.map((tool: any) => tool.name);
291
293
console.log(`Agent has ${attachedTools.length} tools currently attached`);
292
294
···
296
298
297
299
// Create a user-level client for tool operations
298
300
// Tools are user-level resources, not project-scoped
299
-
const { LettaClient } = await import("@letta-ai/letta-client");
300
-
const userLevelClient = new LettaClient({
301
-
token: Deno.env.get("LETTA_API_KEY"),
301
+
const { default: Letta } = await import("@letta-ai/letta-client");
302
+
const userLevelClient = new Letta({
303
+
apiKey: Deno.env.get("LETTA_API_KEY"),
302
304
});
303
305
304
306
// First, process hardcoded required tools
···
311
313
}
312
314
313
315
// Search for the tool in the global registry
314
-
const existingTools = await userLevelClient.tools.list({
316
+
const existingToolsPage = await userLevelClient.tools.list({
315
317
name: toolName,
316
318
});
319
+
const existingTools = existingToolsPage.items;
317
320
318
321
if (existingTools.length > 0) {
319
322
const tool = existingTools[0];
320
323
if (tool.id) {
321
-
await client.agents.tools.attach(agentId, tool.id);
324
+
await client.agents.tools.attach(tool.id, { agent_id: agentId });
322
325
console.log(`✓ Attached required tool: ${toolName}`);
323
326
toolsAttached++;
324
327
}
···
359
362
try {
360
363
// Attempt to create the tool - Letta will extract the function name from docstring
361
364
const createParams: any = {
362
-
sourceCode: toolSource,
365
+
source_code: toolSource,
363
366
};
364
367
365
368
// Add pip requirements if any were detected
366
369
if (pipRequirements.length > 0) {
367
-
createParams.pipRequirements = pipRequirements;
370
+
createParams.pip_requirements = pipRequirements;
368
371
}
369
372
370
373
tool = await userLevelClient.tools.create(createParams);
···
384
387
const funcMatch = toolSource.match(/^def\s+(\w+)\s*\(/m);
385
388
if (funcMatch) {
386
389
const functionName = funcMatch[1];
387
-
const existingTools = await userLevelClient.tools.list({
390
+
const existingToolsPage = await userLevelClient.tools.list({
388
391
name: functionName,
389
392
});
393
+
const existingTools = existingToolsPage.items;
390
394
if (existingTools.length > 0) {
391
395
tool = existingTools[0];
392
396
}
···
409
413
410
414
// Attach the tool to the agent
411
415
if (tool.id) {
412
-
await client.agents.tools.attach(agentId, tool.id);
416
+
await client.agents.tools.attach(tool.id, { agent_id: agentId });
413
417
if (wasCreated) {
414
418
console.log(
415
419
`✓ Created and attached tool: ${toolName} (from ${toolFileName}.py)`,
+8
-23
utils/agentContext.ts
+8
-23
utils/agentContext.ts
···
47
47
return value;
48
48
};
49
49
50
-
export const getLettaProjectName = (): string => {
51
-
const value = Deno.env.get("LETTA_PROJECT_NAME")?.trim();
50
+
const getLettaProjectID = (): string => {
51
+
const value = Deno.env.get("LETTA_PROJECT_ID")?.trim();
52
52
53
53
if (!value?.length) {
54
54
throw Error(
55
-
"Letta Project Name not provided in `.env`. add variable `LETTA_PROJECT_NAME=`.",
55
+
"Letta Project ID not provided in `.env`. add variable `LETTA_PROJECT_ID=`.",
56
+
);
57
+
} else if (!value.includes("-")) {
58
+
throw Error(
59
+
"Letta Project ID is not formed correctly, check variable `LETTA_PROJECT_ID`",
56
60
);
57
61
}
58
62
59
63
return value;
60
64
};
61
-
62
-
//
63
-
// temporarily commenting out until switch to letta SDK 1.0
64
-
//
65
-
// const getLettaProjectID = (): string => {
66
-
// const value = Deno.env.get("LETTA_PROJECT_ID")?.trim();
67
-
68
-
// if (!value?.length) {
69
-
// throw Error(
70
-
// "Letta Project ID not provided in `.env`. add variable `LETTA_PROJECT_ID=`.",
71
-
// );
72
-
// } else if (!value.includes("-")) {
73
-
// throw Error(
74
-
// "Letta Project ID is not formed correctly, check variable `LETTA_PROJECT_ID`",
75
-
// );
76
-
// }
77
-
78
-
// return value;
79
-
// };
80
65
81
66
const getAgentBskyHandle = (): string => {
82
67
const value = Deno.env.get("BSKY_USERNAME")?.trim();
···
568
553
replyCount: 0,
569
554
quoteCount: 0,
570
555
// required with manual variables
571
-
lettaProjectIdentifier: getLettaProjectName(),
556
+
lettaProjectIdentifier: getLettaProjectID(),
572
557
agentBskyHandle: getAgentBskyHandle(),
573
558
agentBskyName: await getAgentBskyName(),
574
559
agentBskyDID: setAgentBskyDID(),
+26
-25
utils/messageAgent.ts
+26
-25
utils/messageAgent.ts
···
1
-
import { LettaClient } from "@letta-ai/letta-client";
1
+
import Letta from "@letta-ai/letta-client";
2
2
import { agentContext } from "./agentContext.ts";
3
3
// Helper function to format tool arguments as inline key-value pairs
4
4
const formatArgsInline = (args: unknown): string => {
···
28
28
return `${str.slice(0, maxLength)}... (truncated, ${str.length} total chars)`;
29
29
};
30
30
31
-
export const client = new LettaClient({
32
-
token: Deno.env.get("LETTA_API_KEY"),
33
-
project: Deno.env.get("LETTA_PROJECT_NAME"),
31
+
export const client = new Letta({
32
+
apiKey: Deno.env.get("LETTA_API_KEY"),
33
+
// @ts-ignore: Letta SDK type definition might be slightly off or expecting different casing
34
+
projectId: Deno.env.get("LETTA_PROJECT_ID"),
34
35
});
35
36
36
37
export const messageAgent = async (prompt: string) => {
37
38
const agent = Deno.env.get("LETTA_AGENT_ID");
38
39
39
40
if (agent) {
40
-
const reachAgent = await client.agents.messages.createStream(agent, {
41
+
const reachAgent = await client.agents.messages.stream(agent, {
41
42
messages: [
42
43
{
43
-
role: "user",
44
-
content: [
45
-
{
46
-
type: "text",
47
-
text: prompt,
48
-
},
49
-
],
44
+
role: "system",
45
+
content: prompt,
50
46
},
51
47
],
52
-
streamTokens: true,
48
+
stream_tokens: true,
53
49
});
54
50
55
51
for await (const response of reachAgent) {
56
-
if (response.messageType === "reasoning_message") {
52
+
if (response.message_type === "reasoning_message") {
57
53
// console.log(`💭 reasoning…`);
58
-
} else if (response.messageType === "assistant_message") {
54
+
} else if (response.message_type === "assistant_message") {
59
55
console.log(`💬 ${agentContext.agentBskyName}: ${response.content}`);
60
-
} else if (response.messageType === "tool_call_message") {
61
-
const formattedArgs = formatArgsInline(response.toolCall.arguments);
62
-
console.log(
63
-
`🗜️ tool called: ${response.toolCall.name} with args: ${formattedArgs}`,
64
-
);
65
-
} else if (response.messageType === "tool_return_message") {
66
-
const toolReturn = response.toolReturn;
56
+
} else if (response.message_type === "tool_call_message") {
57
+
if (
58
+
Array.isArray(response.tool_calls) && response.tool_calls.length > 0
59
+
) {
60
+
const toolCall = response.tool_calls[0];
61
+
const formattedArgs = formatArgsInline(toolCall.arguments);
62
+
console.log(
63
+
`🗜️ tool called: ${toolCall.name} with args: ${formattedArgs}`,
64
+
);
65
+
}
66
+
} else if (response.message_type === "tool_return_message") {
67
+
const toolReturn = response.tool_returns;
67
68
const returnStr = typeof toolReturn === "string"
68
69
? toolReturn
69
70
: JSON.stringify(toolReturn);
70
71
console.log(`🔧 tool response: ${truncateString(returnStr)}`);
71
-
} else if (response.messageType === "usage_statistics") {
72
-
console.log(`🔢 total steps: ${response.stepCount}`);
73
-
} else if (response.messageType === "hidden_reasoning_message") {
72
+
} else if (response.message_type === "usage_statistics") {
73
+
console.log(`🔢 total steps: ${response.step_count}`);
74
+
} else if (response.message_type === "hidden_reasoning_message") {
74
75
console.log(`hidden reasoning…`);
75
76
}
76
77
}