Skip to content

Commit

Permalink
first pass refinemetns to match the rest
Browse files Browse the repository at this point in the history
  • Loading branch information
stat committed Nov 8, 2024
1 parent ab452a1 commit f679c94
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
from cdp_agentkit_core.actions.social.twitter.account_details import (
ACCOUNT_DETAILS_PROMPT as ACCOUNT_DETAILS_PROMPT,
)
from cdp_agentkit_core.actions.social.twitter.account_details import (
AccountDetailsInput as AccountDetailsInput,
)
from cdp_agentkit_core.actions.social.twitter.account_details import (
account_details as account_details,
)
from cdp_agentkit_core.actions.social.twitter.post_tweet import (
POST_TWEET_PROMPT as POST_TWEET_PROMPT,
)
from cdp_agentkit_core.actions.social.twitter.post_tweet import PostTweetInput as PostTweetInput
from cdp_agentkit_core.actions.social.twitter.post_tweet import post_tweet as post_tweet
from cdp_agentkit_core.actions.social.twitter.action import TwitterAction
from cdp_agentkit_core.actions.social.twitter.account_details import AccountDetailsAction
from cdp_agentkit_core.actions.social.twitter.post_tweet import PostTweetAction

def get_all_twitter_actions() -> list[type[TwitterAction]]:
actions = []
for action in TwitterAction.__subclasses__():
actions.append(action())

return actions

TWITTER_ACTIONS = get_all_twitter_actions()

__all__ = [
"TwitterAction",
"AccountDetailsAction",
"PostTweetAction",
"TWITTER_ACTIONS",
]
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
from collections.abc import Callable

import tweepy
from pydantic import BaseModel, Field

from cdp_agentkit_core.actions.social.twitter.action import TwitterAction

ACCOUNT_DETAILS_PROMPT = """
This tool will return account details for the currently authenticated Twitter (X) user context."""


class AccountDetailsInput(BaseModel):
"""Input argument schema for Twitter account details action."""

no_input: str = Field(
"",
description="No input required, e.g. `` (empty string).",
)


def account_details(client: tweepy.Client) -> str:
"""Get the authenticated Twitter (X) user account details.
Args:
client (tweepy.Client): The Twitter (X) client used to authenticate with.
Returns:
str: A message containing account details for the authenticated user context.
Expand All @@ -36,3 +37,11 @@ def account_details(client: tweepy.Client) -> str:
message = f"Error retrieving authenticated user account details: {e}"

return message

class AccountDetailsAction(TwitterAction):
"""Twitter (X) account details action."""

name: str = "account_details"
description:str = ACCOUNT_DETAILS_PROMPT
args_schema: type[BaseModel] | None = AccountDetailsInput
func: Callable[..., str] = account_details
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from collections.abc import Callable

import tweepy
from pydantic import BaseModel, Field

from cdp_agentkit_core.actions.social.twitter import TwitterAction

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."""

Expand Down Expand Up @@ -34,3 +38,11 @@ def post_tweet(client: tweepy.Client, tweet: str) -> str:
message = f"Error posting to Twitter:\n{tweet}\n{e}"

return message

class PostTweetAction(TwitterAction):
"""Twitter (X) post tweet action."""

name: str = "post_tweet"
description: str = POST_TWEET_PROMPT
args_schema: type[BaseModel] | None = PostTweetInput
func: Callable[..., str] = post_tweet
10 changes: 5 additions & 5 deletions twitter-langchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ pip install twitter-langchain
Set the following environment variables:

```bash
OPENAI_API_KEY=<your-openai-api-key>
TWITTER_API_KEY=<your-api-key>
TWITTER_API_SECRET=<your-api-secret>
TWITTER_ACCESS_TOKEN=<your-access-token>
TWITTER_ACCESS_TOKEN_SECRET=<your-access-token-secret>
export OPENAI_API_KEY=<your-openai-api-key>
export TWITTER_API_KEY=<your-api-key>
export TWITTER_API_SECRET=<your-api-secret>
export TWITTER_ACCESS_TOKEN=<your-access-token>
export TWITTER_ACCESS_TOKEN_SECRET=<your-access-token-secret>
```

## Usage
Expand Down
4 changes: 2 additions & 2 deletions twitter-langchain/twitter_langchain/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""CDP Twitter Toolkit."""

from twitter_langchain.twitter_action import TwitterAction
from twitter_langchain.twitter_api_wrapper import TwitterApiWrapper
from twitter_langchain.twitter_tool import TwitterTool
from twitter_langchain.twitter_toolkit import TwitterToolkit

__all__ = [
"TwitterAction",
"TwitterApiWrapper",
"TwitterTool",
"TwitterToolkit",
]
42 changes: 10 additions & 32 deletions twitter-langchain/twitter_langchain/twitter_api_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
"""Util that calls Twitter API."""

import inspect
from collections.abc import Callable
from typing import Any

from cdp_agentkit_core.actions.social.twitter import (
account_details,
post_tweet,
)
from langchain_core.utils import get_from_dict_or_env
from pydantic import BaseModel, model_validator

Expand Down Expand Up @@ -46,34 +44,14 @@ def validate_environment(cls, values: dict) -> Any:

return values

def account_details_wrapper(self) -> str:
"""Get the authenticated Twitter (X) user account details.
def run_action(self, func: Callable[..., str], **kwargs) -> str:
"""Run a Twitter Action."""
import tweepy

Returns:
str: A message containing account details for the authenticated user context in JSON format.
func_signature = inspect.signature(func)
first_kwarg = next(iter(func_signature.parameters.values()), None)

"""
return account_details(client=self.client)

def post_tweet_wrapper(self, tweet: str) -> str:
"""Post tweet to Twitter.
Args:
client (tweepy.Client): The tweepy client to use.
tweet (str): The text of the tweet to post to twitter. Tweets can be maximum 280 characters.
Returns:
str: A message containing the result of the post action and the tweet.
"""
return post_tweet(client=self.client, tweet=tweet)

def run(self, mode: str, **kwargs) -> str:
"""Run the action via the Twitter API."""
if mode == "account_details":
return self.account_details_wrapper()
elif mode == "post_tweet":
return self.post_tweet_wrapper(**kwargs)
if first_kwarg and first_kwarg.annotation is tweepy.Client:
return func(self.client, **kwargs)
else:
raise ValueError("Invalid mode: " + mode)

return func(**kwargs)
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
"""Tool allows agents to interact with the Twitter API."""
"""Tool allows agents to interact with the Twitter API.
To use this tool, you must first set as environment variables:
OPENAI_API_KEY
TWITTER_API_KEY
TWITTER_API_SECRET
TWITTER_ACCESS_TOKEN
TWITTER_ACCESS_TOKEN_SECRET
"""

from collections.abc import Callable
from typing import Any

from langchain_core.callbacks import CallbackManagerForToolRun
Expand All @@ -9,14 +19,14 @@
from twitter_langchain.twitter_api_wrapper import TwitterApiWrapper


class TwitterAction(BaseTool): # type: ignore[override]
class TwitterTool(BaseTool): # type: ignore[override]
"""Tool for interacting with the Twitter API."""

twitter_api_wrapper: TwitterApiWrapper
mode: str
name: str = ""
description: str = ""
args_schema: type[BaseModel] | None = None
func: Callable[..., str]

def _run(
self,
Expand All @@ -33,4 +43,4 @@ def _run(
parsed_input_args = validated_input_data.model_dump()
else:
parsed_input_args = {"instructions": instructions}
return self.twitter_api_wrapper.run(self.mode, **parsed_input_args)
return self.twitter_api_wrapper.run_action(self.func, **parsed_input_args)
36 changes: 10 additions & 26 deletions twitter-langchain/twitter_langchain/twitter_toolkit.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
"""TwitterToolkit."""

from cdp_agentkit_core.actions.social.twitter import (
ACCOUNT_DETAILS_PROMPT,
POST_TWEET_PROMPT,
AccountDetailsInput,
PostTweetInput,
)
from cdp_agentkit_core.actions.social.twitter import TWITTER_ACTIONS

from langchain_core.tools import BaseTool
from langchain_core.tools.base import BaseToolkit

from twitter_langchain.twitter_action import TwitterAction
from twitter_langchain.twitter_api_wrapper import TwitterApiWrapper
from twitter_langchain.twitter_tool import TwitterTool


class TwitterToolkit(BaseToolkit):
Expand Down Expand Up @@ -122,28 +118,16 @@ def from_twitter_api_wrapper(cls, twitter_api_wrapper: TwitterApiWrapper) -> "Tw
TwitterToolkit. The Twitter toolkit.
"""
actions: list[dict] = [
{
"mode": "account_details",
"name": "account_details",
"description": ACCOUNT_DETAILS_PROMPT,
"args_schema": AccountDetailsInput,
},
{
"mode": "post_tweet",
"name": "post_tweet",
"description": POST_TWEET_PROMPT,
"args_schema": PostTweetInput,
},
]

actions = TWITTER_ACTIONS

tools = [
TwitterAction(
name=action["name"],
description=action["description"],
mode=action["mode"],
TwitterTool(
name=action.name,
description=action.description,
twitter_api_wrapper=twitter_api_wrapper,
args_schema=action.get("args_schema", None),
args_schema=action.args_schema,
func=action.func,
)
for action in actions
]
Expand Down

0 comments on commit f679c94

Please sign in to comment.