From 3cdd45d62315f74a8b992bb409d5c6e1830bf3e8 Mon Sep 17 00:00:00 2001 From: Deepak Date: Fri, 27 Dec 2024 16:53:12 +0530 Subject: [PATCH] added write functionalities ie, swap and transfer --- examples/agent-kit-langgraph/package.json | 6 +- examples/agent-kit-langgraph/pnpm-lock.yaml | 292 +++++++++++++++++- .../src/agents/generalAgent.ts | 13 +- .../agent-kit-langgraph/src/agents/manager.ts | 23 ++ .../src/agents/transferOrSwap.ts | 25 ++ .../src/helper/examples.ts | 5 + .../src/helper/tokenList.ts | 50 +++ examples/agent-kit-langgraph/src/index.ts | 21 +- .../src/prompts/manager.ts | 48 +++ .../src/prompts/transferSwap.ts | 43 +++ .../agent-kit-langgraph/src/tools/swap.ts | 45 +++ .../agent-kit-langgraph/src/utils/route.ts | 14 + .../src/utils/solanaAgent.ts | 4 +- 13 files changed, 572 insertions(+), 17 deletions(-) create mode 100644 examples/agent-kit-langgraph/src/agents/manager.ts create mode 100644 examples/agent-kit-langgraph/src/agents/transferOrSwap.ts create mode 100644 examples/agent-kit-langgraph/src/helper/examples.ts create mode 100644 examples/agent-kit-langgraph/src/helper/tokenList.ts create mode 100644 examples/agent-kit-langgraph/src/prompts/manager.ts create mode 100644 examples/agent-kit-langgraph/src/prompts/transferSwap.ts create mode 100644 examples/agent-kit-langgraph/src/tools/swap.ts diff --git a/examples/agent-kit-langgraph/package.json b/examples/agent-kit-langgraph/package.json index b88b54b..10c057d 100644 --- a/examples/agent-kit-langgraph/package.json +++ b/examples/agent-kit-langgraph/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "dev": "node --loader ts-node/esm" + "dev": "tsx" }, "keywords": [], "author": "", @@ -16,10 +16,12 @@ "@langchain/core": "^0.3.26", "@langchain/langgraph": "^0.2.36", "dotenv": "^16.4.7", - "solana-agent-kit": "^1.3.0" + "solana-agent-kit": "^1.3.0", + "zod": "^3.24.1" }, "devDependencies": { "ts-node": "^10.9.2", + "tsx": "^4.19.2", "typescript": "^5.0.0" }, "ts-node": { diff --git a/examples/agent-kit-langgraph/pnpm-lock.yaml b/examples/agent-kit-langgraph/pnpm-lock.yaml index 65fa0b7..776093b 100644 --- a/examples/agent-kit-langgraph/pnpm-lock.yaml +++ b/examples/agent-kit-langgraph/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@langchain/community': specifier: ^0.3.20 - version: 0.3.20(@browserbasehq/sdk@2.0.0)(@browserbasehq/stagehand@1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1))(@ibm-cloud/watsonx-ai@1.3.0)(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1))))(axios@1.7.4)(ibm-cloud-sdk-core@5.1.0)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.77.0(zod@3.24.1))(playwright@1.49.1)(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 0.3.20(@browserbasehq/sdk@2.0.0)(@browserbasehq/stagehand@1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1))(@ibm-cloud/watsonx-ai@1.3.0)(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1))))(axios@1.7.4)(ibm-cloud-sdk-core@5.1.0)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.77.0(zod@3.24.1))(playwright@1.49.1)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@langchain/core': specifier: ^0.3.26 version: 0.3.26(openai@4.77.0(zod@3.24.1)) @@ -23,10 +23,16 @@ importers: solana-agent-kit: specifier: ^1.3.0 version: 1.3.0(@noble/hashes@1.6.1)(axios@1.7.4)(borsh@2.0.0)(buffer@6.0.3)(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.24.1) + zod: + specifier: ^3.24.1 + version: 3.24.1 devDependencies: ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@18.19.68)(typescript@5.6.3) + tsx: + specifier: ^4.19.2 + version: 4.19.2 typescript: specifier: ^5.0.0 version: 5.6.3 @@ -82,6 +88,150 @@ packages: '@emnapi/runtime@1.3.1': resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@ethersproject/bytes@5.7.0': resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} @@ -1338,6 +1488,11 @@ packages: es6-promisify@5.0.0: resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -1407,6 +1562,11 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -1414,6 +1574,9 @@ packages: resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==} engines: {node: '>= 0.4'} + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -1831,6 +1994,9 @@ packages: requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + retry-axios@2.6.0: resolution: {integrity: sha512-pOLi+Gdll3JekwuFjXO3fTq+L9lzMQGcSq7M5gIjExcl3Gu1hd4XXuf5o3+LuSBsaULQH7DiNbsqPd1chVpQGQ==} engines: {node: '>=10.7.0'} @@ -1953,6 +2119,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.19.2: + resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==} + engines: {node: '>=18.0.0'} + hasBin: true + tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} @@ -2207,6 +2378,78 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.23.1': + optional: true + + '@esbuild/android-arm64@0.23.1': + optional: true + + '@esbuild/android-arm@0.23.1': + optional: true + + '@esbuild/android-x64@0.23.1': + optional: true + + '@esbuild/darwin-arm64@0.23.1': + optional: true + + '@esbuild/darwin-x64@0.23.1': + optional: true + + '@esbuild/freebsd-arm64@0.23.1': + optional: true + + '@esbuild/freebsd-x64@0.23.1': + optional: true + + '@esbuild/linux-arm64@0.23.1': + optional: true + + '@esbuild/linux-arm@0.23.1': + optional: true + + '@esbuild/linux-ia32@0.23.1': + optional: true + + '@esbuild/linux-loong64@0.23.1': + optional: true + + '@esbuild/linux-mips64el@0.23.1': + optional: true + + '@esbuild/linux-ppc64@0.23.1': + optional: true + + '@esbuild/linux-riscv64@0.23.1': + optional: true + + '@esbuild/linux-s390x@0.23.1': + optional: true + + '@esbuild/linux-x64@0.23.1': + optional: true + + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + + '@esbuild/openbsd-x64@0.23.1': + optional: true + + '@esbuild/sunos-x64@0.23.1': + optional: true + + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-x64@0.23.1': + optional: true + '@ethersproject/bytes@5.7.0': dependencies: '@ethersproject/logger': 5.7.0 @@ -2311,7 +2554,7 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@langchain/community@0.3.20(@browserbasehq/sdk@2.0.0)(@browserbasehq/stagehand@1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1))(@ibm-cloud/watsonx-ai@1.3.0)(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1))))(axios@1.7.4)(ibm-cloud-sdk-core@5.1.0)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.77.0(zod@3.24.1))(playwright@1.49.1)(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@langchain/community@0.3.20(@browserbasehq/sdk@2.0.0)(@browserbasehq/stagehand@1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1))(@ibm-cloud/watsonx-ai@1.3.0)(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1))))(axios@1.7.4)(ibm-cloud-sdk-core@5.1.0)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.77.0(zod@3.24.1))(playwright@1.49.1)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@browserbasehq/stagehand': 1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1) '@ibm-cloud/watsonx-ai': 1.3.0 @@ -2333,7 +2576,7 @@ snapshots: jsonwebtoken: 9.0.2 lodash: 4.17.21 playwright: 1.49.1 - ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - '@langchain/anthropic' - '@langchain/aws' @@ -3324,6 +3567,33 @@ snapshots: dependencies: es6-promise: 4.2.8 + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + event-target-shim@5.0.1: {} eventemitter3@4.0.7: {} @@ -3380,6 +3650,9 @@ snapshots: fsevents@2.3.2: optional: true + fsevents@2.3.3: + optional: true + function-bind@1.1.2: {} get-intrinsic@1.2.6: @@ -3395,6 +3668,10 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + gopd@1.2.0: {} graceful-fs@4.2.11: @@ -3835,6 +4112,8 @@ snapshots: requires-port@1.0.0: {} + resolve-pkg-maps@1.0.0: {} + retry-axios@2.6.0(axios@1.7.4): dependencies: axios: 1.7.4(debug@4.4.0) @@ -4046,6 +4325,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.19.2: + dependencies: + esbuild: 0.23.1 + get-tsconfig: 4.8.1 + optionalDependencies: + fsevents: 2.3.3 + tweetnacl@1.0.3: {} typedoc@0.26.11(typescript@5.6.3): diff --git a/examples/agent-kit-langgraph/src/agents/generalAgent.ts b/examples/agent-kit-langgraph/src/agents/generalAgent.ts index da9e1fa..4ea9faf 100644 --- a/examples/agent-kit-langgraph/src/agents/generalAgent.ts +++ b/examples/agent-kit-langgraph/src/agents/generalAgent.ts @@ -1,8 +1,7 @@ import { createReactAgent } from "@langchain/langgraph/prebuilt"; -import { gpt4o } from "../utils/model.js"; -import { solanaAgentState } from "../utils/state.js"; +import { gpt4o } from "../utils/model"; +import { solanaAgentState } from "../utils/state"; import { TavilySearchResults } from "@langchain/community/tools/tavily_search"; -import { HumanMessage } from "@langchain/core/messages"; // Initialize tools array const searchTools = []; @@ -12,7 +11,7 @@ if (process.env.TAVILY_API_KEY) { searchTools.push(new TavilySearchResults()); } -export const generalAgent = createReactAgent({ +const generalAgent = createReactAgent({ llm: gpt4o, tools: searchTools, }); @@ -24,9 +23,3 @@ export const generalistNode = async (state: typeof solanaAgentState.State) => { return { messages: [...result.messages] }; }; - -const messages = [new HumanMessage("What is the best way to buy SOL?")]; - -const result = await generalAgent.invoke({ messages }); - -console.log(result.messages); diff --git a/examples/agent-kit-langgraph/src/agents/manager.ts b/examples/agent-kit-langgraph/src/agents/manager.ts new file mode 100644 index 0000000..70e734b --- /dev/null +++ b/examples/agent-kit-langgraph/src/agents/manager.ts @@ -0,0 +1,23 @@ +import { prompt, parser } from "../prompts/manager"; +import { RunnableSequence } from "@langchain/core/runnables"; +import { solanaAgentState } from "../utils/state"; +import { gpt4o } from "../utils/model"; + +const chain = RunnableSequence.from([prompt, gpt4o, parser]); + +export const managerNode = async (state: typeof solanaAgentState.State) => { + const { messages } = state; + + const result = await chain.invoke({ + formatInstructions: parser.getFormatInstructions(), + messages: messages, + }); + + const { isSolanaReadQuery, isSolanaWriteQuery, isGeneralQuery } = result; + + return { + isSolanaReadQuery, + isSolanaWriteQuery, + isGeneralQuery, + }; +}; diff --git a/examples/agent-kit-langgraph/src/agents/transferOrSwap.ts b/examples/agent-kit-langgraph/src/agents/transferOrSwap.ts new file mode 100644 index 0000000..552d236 --- /dev/null +++ b/examples/agent-kit-langgraph/src/agents/transferOrSwap.ts @@ -0,0 +1,25 @@ +import { gpt4o } from "../utils/model"; +import { agentKit } from "../utils/solanaAgent"; +import { solanaAgentState } from "../utils/state"; +import { createReactAgent } from "@langchain/langgraph/prebuilt"; +import { SolanaTransferTool } from "solana-agent-kit/dist/langchain"; +import { transferSwapPrompt } from "../prompts/transferSwap"; +import { swapTool } from "../tools/swap"; + +const transferOrSwapAgent = createReactAgent({ + stateModifier: transferSwapPrompt, + llm: gpt4o, + tools: [new SolanaTransferTool(agentKit), swapTool], +}); + +export const transferSwapNode = async ( + state: typeof solanaAgentState.State, +) => { + const { messages } = state; + + const result = await transferOrSwapAgent.invoke({ + messages, + }); + + return result; +}; diff --git a/examples/agent-kit-langgraph/src/helper/examples.ts b/examples/agent-kit-langgraph/src/helper/examples.ts new file mode 100644 index 0000000..d88dcd2 --- /dev/null +++ b/examples/agent-kit-langgraph/src/helper/examples.ts @@ -0,0 +1,5 @@ +import { HumanMessage } from "@langchain/core/messages"; + +export const generalQuestion = [ + new HumanMessage("Who is the president of Ecuador?"), +]; diff --git a/examples/agent-kit-langgraph/src/helper/tokenList.ts b/examples/agent-kit-langgraph/src/helper/tokenList.ts new file mode 100644 index 0000000..92a2b67 --- /dev/null +++ b/examples/agent-kit-langgraph/src/helper/tokenList.ts @@ -0,0 +1,50 @@ +export const tokenList = [ + { + name: "USDC", + ticker: "USDC", + decimal: 6, + mintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + }, + { + name: "USDT", + ticker: "USDT", + decimal: 6, + mintAddress: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", + }, + { + name: "USDS", + ticker: "USDS", + decimal: 6, + mintAddress: "USDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA", + }, + { + name: "SOL", + ticker: "SOL", + decimal: 9, + mintAddress: "So11111111111111111111111111111111111111112", + }, + { + name: "jitoSOL", + ticker: "jitoSOL", + decimal: 9, + mintAddress: "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", + }, + { + name: "bSOL", + ticker: "bSOL", + decimal: 9, + mintAddress: "bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1", + }, + { + name: "mSOL", + ticker: "mSOL", + decimal: 9, + mintAddress: "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So", + }, + { + name: "BONK", + ticker: "BONK", + decimal: 9, + mintAddress: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263", + }, +]; diff --git a/examples/agent-kit-langgraph/src/index.ts b/examples/agent-kit-langgraph/src/index.ts index 8327600..5ac5302 100644 --- a/examples/agent-kit-langgraph/src/index.ts +++ b/examples/agent-kit-langgraph/src/index.ts @@ -1,6 +1,25 @@ import { StateGraph } from "@langchain/langgraph"; import { solanaAgentState } from "./utils/state"; +import { generalistNode } from "./agents/generalAgent"; +import { transferSwapNode } from "./agents/transferOrSwap"; +import { managerNode } from "./agents/manager"; +import { START, END } from "@langchain/langgraph"; +import { managerRouter } from "./utils/route"; +import { HumanMessage } from "@langchain/core/messages"; -const workflow = new StateGraph(solanaAgentState); +const workflow = new StateGraph(solanaAgentState) + .addNode("generalist", generalistNode) + .addNode("manager", managerNode) + .addNode("transferSwap", transferSwapNode) + .addEdge(START, "manager") + .addConditionalEdges("manager", managerRouter) + .addEdge("generalist", END) + .addEdge("transferSwap", END); export const graph = workflow.compile(); + +const result = await graph.invoke({ + messages: [new HumanMessage("swap 0.1 usdc to sol")], +}); + +console.log(result); diff --git a/examples/agent-kit-langgraph/src/prompts/manager.ts b/examples/agent-kit-langgraph/src/prompts/manager.ts new file mode 100644 index 0000000..a70e581 --- /dev/null +++ b/examples/agent-kit-langgraph/src/prompts/manager.ts @@ -0,0 +1,48 @@ +import { StructuredOutputParser } from "@langchain/core/output_parsers"; +import { z } from "zod"; +import { PromptTemplate } from "@langchain/core/prompts"; + +export const parser = StructuredOutputParser.fromZodSchema( + z.object({ + isSolanaReadQuery: z + .boolean() + .describe("Query requires reading data from Solana blockchain"), + isSolanaWriteQuery: z + .boolean() + .describe("Query requires writing/modifying data on Solana blockchain"), + isGeneralQuery: z + .boolean() + .describe("Query is about non-blockchain topics"), + }), +); + +export const prompt = PromptTemplate.fromTemplate( + ` + You are the Chief Routing Officer for a multi-blockchain agent network. Your role is to: + 1. Analyze and classify incoming queries + 2. Determine if the query requires Solana read operations, write operations, or is general + + Format your response according to: + {formatInstructions} + + Classification Guidelines: + - Solana Read Operations include: + * Checking account balances + * Viewing NFT metadata + * Getting program data + * Querying transaction history + * Checking token prices or holdings + - Solana Write Operations include: + * Creating or updating programs + * Sending tokens or SOL + * Minting NFTs + * Creating accounts + * Any transaction that modifies blockchain state + - General queries include: + * Non-blockchain topics + * Internet searches + * General knowledge questions + + \n {messages} \n + `, +); diff --git a/examples/agent-kit-langgraph/src/prompts/transferSwap.ts b/examples/agent-kit-langgraph/src/prompts/transferSwap.ts new file mode 100644 index 0000000..b71d6a9 --- /dev/null +++ b/examples/agent-kit-langgraph/src/prompts/transferSwap.ts @@ -0,0 +1,43 @@ +import { + ChatPromptTemplate, + MessagesPlaceholder, +} from "@langchain/core/prompts"; +import { tokenList } from "../helper/tokenList"; + +// Convert token list to a more readable format for the prompt +const formattedTokenList = tokenList + .map( + (token) => + `- ${token.name} (${token.ticker}) - Decimals: ${token.decimal} - Address: ${token.mintAddress}`, + ) + .join("\n "); + +export const transferSwapPrompt = ChatPromptTemplate.fromMessages([ + [ + "system", + `You are an agent that is an expert in Solana transactions, specialized in token transfers and swaps. You can execute these transactions using the available tools based on user input. + + When processing token amounts: + 1. Use EXACTLY the decimal amount specified by the user without any modifications + 2. Do not round or adjust the numbers + 3. Maintain precise decimal places as provided in the user input + + For transfers: + - User must specify the token, amount, and recipient address + - The same token will be used for input and output + + For swaps: + - User must specify the input token, output token, and amount to swap + - Input and output tokens must be different + - Select tokens from this list of supported tokens: + + ${formattedTokenList} + + Example amounts: + If you say "0.01 SOL", I will use exactly 0.01 (not 0.010 or 0.0100) + If you say "1.234 USDC", I will use exactly 1.234 (not 1.23 or 1.2340) + For swaps, have the slippage be 200 bps + `, + ], + new MessagesPlaceholder("messages"), +]); diff --git a/examples/agent-kit-langgraph/src/tools/swap.ts b/examples/agent-kit-langgraph/src/tools/swap.ts new file mode 100644 index 0000000..3c72bc4 --- /dev/null +++ b/examples/agent-kit-langgraph/src/tools/swap.ts @@ -0,0 +1,45 @@ +import { agentKit } from "../utils/solanaAgent"; +import { tool } from "@langchain/core/tools"; +import { z } from "zod"; +import { PublicKey } from "@solana/web3.js"; + +export const swapTool = tool( + async ({ outputMint, inputAmount, inputMint, inputDecimal }) => { + try { + const inputAmountWithDecimals = inputAmount * 10 ** inputDecimal; + const outputMintAddress = new PublicKey(outputMint); + const inputMintAddress = new PublicKey(inputMint); + + console.log(inputAmountWithDecimals, outputMintAddress, inputMintAddress); + const tx = await agentKit.trade( + outputMintAddress, + inputAmountWithDecimals, + inputMintAddress, + 200, + ); + return tx; + } catch (error) { + console.error(error); + return "error"; + } + }, + { + name: "swap", + description: + "call to swap/trade tokens from one token to the other using Jupiter exchange", + schema: z.object({ + outputMint: z + .string() + .describe("The mint address of destination token to be swapped to"), + inputAmount: z + .number() + .describe( + "the input amount of the token to be swapped without adding any decimals", + ), + inputMint: z.string().describe("The mint address of the origin token "), + inputDecimal: z + .number() + .describe("The decimal of the input token that is being traded"), + }), + }, +); diff --git a/examples/agent-kit-langgraph/src/utils/route.ts b/examples/agent-kit-langgraph/src/utils/route.ts index e69de29..bb45fae 100644 --- a/examples/agent-kit-langgraph/src/utils/route.ts +++ b/examples/agent-kit-langgraph/src/utils/route.ts @@ -0,0 +1,14 @@ +import { solanaAgentState } from "./state"; +import { END } from "@langchain/langgraph"; + +export const managerRouter = (state: typeof solanaAgentState.State) => { + const { isSolanaReadQuery, isSolanaWriteQuery, isGeneralQuery } = state; + + if (isGeneralQuery) { + return "generalist"; + } else if (isSolanaWriteQuery) { + return "transferSwap"; + } else { + return END; + } +}; diff --git a/examples/agent-kit-langgraph/src/utils/solanaAgent.ts b/examples/agent-kit-langgraph/src/utils/solanaAgent.ts index f4c1c8c..ac714e4 100644 --- a/examples/agent-kit-langgraph/src/utils/solanaAgent.ts +++ b/examples/agent-kit-langgraph/src/utils/solanaAgent.ts @@ -1,7 +1,9 @@ -import { SolanaAgentKit } from "solana-agent-kit"; +import { SolanaAgentKit, createSolanaTools } from "solana-agent-kit"; export const agentKit = new SolanaAgentKit( process.env.SOLANA_PRIVATE_KEY!, process.env.RPC_URL!, process.env.OPENAI_API_KEY!, ); + +export const solanaTools = createSolanaTools(agentKit);