a tool to help your Letta AI agents navigate bluesky

Merge pull request #9 from taurean/letta-sdk-upgrade

Letta sdk upgrade

authored by taurean.bryant.land and committed by GitHub 6ed16858 b50ca075

+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
··· 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
··· 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
··· 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
··· 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 }