Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

feat: twitter langchain #18

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3cac1d2
first pass implementing twitter langchain
Dec 5, 2024
68b6fb9
twitter langchain chatbot example
Dec 5, 2024
95ad4c8
jsdoc for twitter langchain
Dec 5, 2024
d92d97b
refinements for twitter langchain
Dec 5, 2024
4d53a1a
chatbot functional
Dec 6, 2024
b97adc4
refinements
stat Dec 6, 2024
98b334b
readme fix
stat Dec 6, 2024
21495ec
adjust chatbot comment
stat Dec 6, 2024
b8bb4f5
readme updates for badges
stat Dec 6, 2024
7e6111e
adjusting unnecessairy promise return
stat Dec 6, 2024
6e9e0bd
updates for chatbot
stat Dec 6, 2024
2c5b31b
typo
stat Dec 6, 2024
1ba0be2
adjusting agentkit zod min to nonempty
stat Dec 6, 2024
b5bf964
Updating READMEs to include Twitter info
derek-cb Dec 6, 2024
c353e7a
Adding (X) to Twitter
derek-cb Dec 6, 2024
850cbba
Removing cdp-langchain chatbot's jest config, adding twitter-langchai…
derek-cb Dec 6, 2024
10c6257
reverting user mentions to account mentions
stat Dec 6, 2024
eb2b905
Moving Twitter actions to cdp-agentkit-core
derek-cb Dec 6, 2024
f3d419c
removing types from jsdoc comments
stat Dec 6, 2024
abc15e4
gha for twitter langchain
stat Dec 6, 2024
3a3fde3
Merge branch 'christopher.gerber/feat/twitter-langchain' of https://g…
derek-cb Dec 6, 2024
936283d
Merge branch 'christopher.gerber/feat/twitter-langchain' of https://g…
derek-cb Dec 6, 2024
18f6b12
linting
stat Dec 6, 2024
3fef8d4
Merge branch 'christopher.gerber/feat/twitter-langchain' of https://g…
derek-cb Dec 6, 2024
2f78c81
Updated twitter-langchain package version to be in line w/ python ver…
derek-cb Dec 6, 2024
24d192b
Move twitter action tests to cdp-agentkit-core
derek-cb Dec 6, 2024
eaa71c4
Remove chatbot examples from workspace
derek-cb Dec 6, 2024
181c2e5
exporting twitter action and schema and adding twitter tool test
stat Dec 6, 2024
0cb98ce
linting
stat Dec 6, 2024
3953cd0
chatbot cleanup
stat Dec 6, 2024
c722440
commenting tests
stat Dec 6, 2024
93b5fda
bringing in the latest from master
stat Dec 6, 2024
7293932
Filling in incomplete CHANGELOG details
derek-cb Dec 6, 2024
f8dd695
Merge branch 'christopher.gerber/feat/twitter-langchain' of https://g…
derek-cb Dec 6, 2024
a1fb8fe
linting
stat Dec 6, 2024
f24258c
bringing in the latest from master
stat Dec 6, 2024
646798f
bringing in the latest from master
stat Dec 6, 2024
bb088a2
reverting core exports
stat Dec 6, 2024
96aefad
fixes for build
stat Dec 6, 2024
f796c14
brining in the latest from master
stat Dec 6, 2024
87b63c7
updates for twitter chatbot
stat Dec 6, 2024
d87d522
adding twitter toolkit test
stat Dec 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"multiline-comment-style": ["error", "starred-block"],
"prettier/prettier": "error",
"@typescript-eslint/member-ordering": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_$"
}
],
"jsdoc/tag-lines": ["error", "any", { "startLines": 1 }],
"jsdoc/check-alignment": "error",
"jsdoc/no-undefined-types": "off",
Expand Down
20 changes: 19 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,22 @@ jobs:
run: |
npm install
npm run lint
npm run format
npm run format

lint-twitter-langchain:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "18"
cache: "npm"
# Install dependencies in parent directory first
- run: npm install
# Then install and lint in working directory
- name: Install and lint twitter-langchain
working-directory: ./twitter-langchain
run: |
npm install
npm run lint
npm run format
6 changes: 6 additions & 0 deletions .github/workflows/publish_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ jobs:
mkdir -p docs/cdp-langchain
cp -r cdp-langchain/docs/* docs/cdp-langchain/

# Move twitter-langchain docs
- name: Build Twitter LangChain docs
run: |
mkdir -p docs/twitter-langchain
cp -r twitter-langchain/docs/* docs/twitter-langchain/

# Deploy to GitHub Pages
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/publish_twitter_langchain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Publish Twitter LangChain to NPM

on:
workflow_dispatch:

jobs:
deploy-twitter-langchain:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "18"
registry-url: "https://registry.npmjs.org"
- run: npm i && npm run build
- name: Install, build and publish Twitter (X) langchain
working-directory: ./twitter-langchain
run: |
npm publish --ignore-scripts --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The **Coinbase Developer Platform (CDP) AgentKit for Node.js** simplifies bringi
## Key Features
- **Framework-agnostic**: Common AI Agent primitives that can be used with any AI framework.
- **LangChain.js integration**: Seamless integration with [LangChain.js](https://js.langchain.com/docs/introduction/) for easy agentic workflows. More frameworks coming soon!
- **Twitter (X) integration**: Seamless integration of Langchain with [Twitter (X)](https://developer.twitter.com/en/docs/twitter-api) for easy agentic workflows.
- **Support for various on-chain actions**:

- Faucet for testnet funds
Expand Down Expand Up @@ -37,6 +38,10 @@ See [CDP AgentKit Core](./cdp-agentkit-core/README.md) to get started!
LangChain.js Toolkit extension of CDP AgentKit. Enables agentic workflows to interact with onchain actions.
See [CDP LangChain](./cdp-langchain/README.md) to get started!

### @coinbasetwitter-langchain
Langchain Toolkit extension for Twitter (X). Enables agentic workflows to interact with Twitter, such as to post a tweet.
See [Twitter Langchain](./twitter-langchain/README.md) to get started!

## Contributing
CDP AgentKit welcomes community contributions.
See [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
Expand All @@ -49,6 +54,7 @@ See [SECURITY.md](SECURITY.md) for more information.
- [CDP AgentKit Documentation](https://docs.cdp.coinbase.com/agentkit/docs/welcome)
- [API Reference: CDP AgentKit Core](https://coinbase.github.io/cdp-agentkit-nodejs/cdp-agentkit-core/index.html)
- [API Reference: CDP AgentKit LangChain Extension](https://coinbase.github.io/cdp-agentkit-nodejs/cdp-langchain/index.html)
- [API Reference: CDP Agentkit Twitter Langchain Extension](https://coinbase.github.io/cdp-agentkit-nodejs/twitter-langchain/index.html)

## License

Expand Down
6 changes: 6 additions & 0 deletions cdp-agentkit-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

- Improved prompts for all actions.

## [0.0.6] - 2024-12-03

### Fixed

Administrative fixes to the release process.

## [0.0.5] - 2024-11-29

### Added
Expand Down
1 change: 1 addition & 0 deletions cdp-agentkit-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
],
"dependencies": {
"@coinbase/coinbase-sdk": "^0.11.0",
"twitter-api-v2": "^1.18.2",
"viem": "^2.21.51",
"zod": "^3.23.8"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* This module provides functionality to retrieve account details for the currently authenticated Twitter (X) user.
*/

import { z } from "zod";
import { TwitterAction } from "./twitter_action";
import { TwitterApi } from "twitter-api-v2";

/**
* Prompt message describing the account details tool.
* A successful response will return account details in JSON format,
* while a failure response will indicate an error from the Twitter API.
*/
const ACCOUNT_DETAILS_PROMPT = `
This tool will return account details for the currently authenticated Twitter (X) user context.

A successful response will return a message with the api response as a json payload:
{"data": {"id": "1853889445319331840", "name": "CDP AgentKit", "username": "CDPAgentKit"}}

A failure response will return a message with a Twitter API request error:
Error retrieving authenticated user account: 429 Too Many Requests
`;

/**
* Input argument schema for the account details action.
*/
export const AccountDetailsInput = z
.object({})
.strip()
.describe("Input schema for retrieving account details");

/**
* Get the authenticated Twitter (X) user account details.
*
* @param client - The Twitter (X) client used to authenticate with.
* @param _ - The input arguments for the action.
* @returns A message containing account details for the authenticated user context.
*/
export async function accountDetails(
client: TwitterApi,
_: z.infer<typeof AccountDetailsInput>,
): Promise<string> {
try {
const response = await client.v2.me();
response.data.url = `https://x.com/${response.data.username}`;
return `Successfully retrieved authenticated user account details:\n${JSON.stringify(response)}`;
} catch (error) {
return `Error retrieving authenticated user account details: ${error}`;
}
}

/**
* Account Details Action
*/
export class AccountDetailsAction implements TwitterAction<typeof AccountDetailsInput> {
public name = "account_details";
public description = ACCOUNT_DETAILS_PROMPT;
public argsSchema = AccountDetailsInput;
public func = accountDetails;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* This module provides functionality to retrieve account mentions from Twitter (X).
*/

import { z } from "zod";
import { TwitterAction } from "./twitter_action";
import { TwitterApi } from "twitter-api-v2";

/**
* Prompt message describing the account mentions tool.
* A successful response will return a message with the API response in JSON format,
* while a failure response will indicate an error from the Twitter API.
*/
const ACCOUNT_MENTIONS_PROMPT = `
This tool will return mentions for the specified Twitter (X) account id.

A successful response will return a message with the API response as a JSON payload:
{"data": [{"id": "1857479287504584856", "text": "@CDPAgentKit reply"}]}

A failure response will return a message with the Twitter API request error:
Error retrieving user mentions: 429 Too Many Requests
`;

/**
* Input argument schema for the account mentions action.
*/
export const AccountMentionsInput = z
.object({
accountId: z
.string()
.nonempty("Account ID is required.")
.describe("The Twitter (X) account id to return mentions for"),
})
.strip()
.describe("Input schema for retrieving account mentions");

/**
* Retrieves mentions for a specified Twitter (X) account.
*
* @param client - The Twitter (X) client used to authenticate with.
* @param args - The input arguments for the action.
* @returns A message indicating the success or failure of the mention retrieval.
*/
export async function accountMentions(
client: TwitterApi,
args: z.infer<typeof AccountMentionsInput>,
): Promise<string> {
try {
const response = await client.v2.userMentionTimeline(args.accountId);
return `Successfully retrieved account mentions:\n${JSON.stringify(response)}`;
} catch (error) {
return `Error retrieving authenticated account mentions: ${error}`;
}
}

/**
* Account Mentions Action
*/
export class AccountMentionsAction implements TwitterAction<typeof AccountMentionsInput> {
public name = "account_mentions";
public description = ACCOUNT_MENTIONS_PROMPT;
public argsSchema = AccountMentionsInput;
public func = accountMentions;
}
40 changes: 40 additions & 0 deletions cdp-agentkit-core/src/actions/cdp/social/twitter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* This module exports various Twitter (X) action instances and their associated types.
*/

import { TwitterAction, TwitterActionSchemaAny } from "./twitter_action";
import { AccountDetailsAction } from "./account_details";
import { AccountMentionsAction } from "./account_mentions";
import { PostTweetAction } from "./post_tweet";
import { PostTweetReplyAction } from "./post_tweet_reply";

/**
* Retrieve an array of Twitter (X) action instances.
*
* @returns {TwitterAction<TwitterActionSchemaAny>[]} An array of Twitter action instances.
*/
export function getAllTwitterActions(): TwitterAction<TwitterActionSchemaAny>[] {
return [
new AccountDetailsAction(),
new AccountMentionsAction(),
new PostTweetReplyAction(),
new PostTweetAction(),
];
}

/**
* All available Twitter (X) actions.
*/
export const TWITTER_ACTIONS = getAllTwitterActions();

/**
* All Twitter (X) action types.
*/
export {
TwitterAction,
TwitterActionSchemaAny,
AccountDetailsAction,
AccountMentionsAction,
PostTweetAction,
PostTweetReplyAction,
};
61 changes: 61 additions & 0 deletions cdp-agentkit-core/src/actions/cdp/social/twitter/post_tweet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* This module provides functionality to post a tweet on Twitter (X).
*/

import { z } from "zod";
import { TwitterAction } from "./twitter_action";
import { TwitterApi } from "twitter-api-v2";

/**
* Prompt message describing the post tweet tool.
* A successful response will return a message with the API response in JSON format,
* while a failure response will indicate an error from the Twitter API.
*/
const POST_TWEET_PROMPT = `
This tool will post a tweet on Twitter. The tool takes the text of the tweet as input. Tweets can be maximum 280 characters.

A successful response will return a message with the API response as a JSON payload:
{"data": {"text": "hello, world!", "id": "0123456789012345678", "edit_history_tweet_ids": ["0123456789012345678"]}}

A failure response will return a message with the Twitter API request error:
You are not allowed to create a Tweet with duplicate content.
`;

/**
* Input argument schema for the post tweet action.
*/
export const PostTweetInput = z
.object({
tweet: z.string().max(280, "Tweet must be a maximum of 280 characters."),
})
.strip()
.describe("Input schema for posting a tweet");

/**
* Posts a tweet on Twitter (X).
*
* @param client - The Twitter (X) client used to authenticate with.
* @param args - The input arguments for the action.
* @returns A message indicating the success or failure of the tweet posting.
*/
export async function postTweet(
client: TwitterApi,
args: z.infer<typeof PostTweetInput>,
): Promise<string> {
try {
const response = await client.v2.tweet(args.tweet);
return `Successfully posted to Twitter:\n${JSON.stringify(response)}`;
} catch (error) {
return `Error posting to Twitter:\n${error}`;
}
}

/**
* Post Tweet Action
*/
export class PostTweetAction implements TwitterAction<typeof PostTweetInput> {
public name = "post_tweet";
public description = POST_TWEET_PROMPT;
public argsSchema = PostTweetInput;
public func = postTweet;
}
Loading
Loading