Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AgentKit] Farcaster Tooling #129

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

derekbrown
Copy link

What changed? Why?

• Added Farcaster tooling to enable AgentKit devs to build integrations that publish casts to Farcaster, similar to sending tweets. Farcaster is a growing network of developers that are excited about both agents and the Base ecosystem, so it seemed like a natural fit.
• As Farcaster doesn't have a centralized API, the tooling relies on Neynar, which has become the industry standard for Farcaster APIs.
• I've only added publish_cast here as an example and as the primary tool I suspect others will use. Others are free to add FC-related tools (account lookups, etc.) as needed.
• I've written baseline docs to get up and running.
• I've provided baseline tests for the tooling and publish_cast tooling.
• I've also added an example chatbot that will publish casts to Farcaster based on the environment variables so that other developers can see it in action.

Qualified Impact

The new tooling introduces a brand new surface area for bugs, similar to the Twitter Agentkit tooling already in existence. I'd suggest fixing forward where appropriate as a fix, but there may be an occasional need for a rollback.

@cb-heimdall
Copy link

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 1
Sum 2

Copy link
Contributor

@John-peterson-coinbase John-peterson-coinbase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will help to also include a get account details action in the initial pass, so the agent has context on the account they control.

A few small comments about how config options are passed to actions. Otherwise LGTM! 🚀

Comment on lines +16 to +30
## Python Development
### Prerequisites
- Python 3.10 or higher
- Rust/Cargo installed ([Rust Installation Instructions](https://doc.rust-lang.org/cargo/getting-started/installation.html))
- Poetry for package management and tooling
- [Poetry Installation Instructions](https://python-poetry.org/docs/#installation)

`cdp-langchain` also requires a [CDP API Key](https://portal.cdp.coinbase.com/access/api).

### Development Tools
#### Formatting
`make format`

#### Linting
- Check linter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want Python instructions to be shipped in the Typescript API Reference Docs CONTRIBUTING.md?

Copy link
Author

@derekbrown derekbrown Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not? I just followed the precedence set in the twitter-langchain docs, but will remove

Comment on lines +41 to +42
const NEYNAR_API_KEY = process.env.NEYNAR_API_KEY;
const SIGNER_UUID = process.env.NEYNAR_MANAGED_SIGNER;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we initialize the API Key / Signer UUID during initializing FarcasterAgentkit and pass the required config to the action when it is run instead of enforcing usage of ENV vars here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can but that's not how the Twitter agentkit operates, and I didn't want to break the already set standard. If we want to make a change here, what I'd recommend is using options to overwrite the environment vars if they're set, and fallback to the env variables.

Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me. I'm aligned with using env vars as a fallback with options that can be explicitly set. This seems like a better pattern than enforcing env vars. Let's establish that pattern here for Farcaster, and I will take an AI to add a options config for twitter as a follow up. Thanks for pointing out the diff.

const SIGNER_UUID = process.env.NEYNAR_MANAGED_SIGNER;

const headers: HeadersInit = {
api_key: NEYNAR_API_KEY!, // Note the changed key format
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the key format change referenced here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its just required, but will remove comment - not that helpful

Comment on lines +57 to +59
console.log(NEYNAR_API_KEY);
console.log(args);
console.log(response);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
console.log(NEYNAR_API_KEY);
console.log(args);
console.log(response);

console.log(args);
console.log(response);
const data = await response.json();
console.log(data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
console.log(data);

Comment on lines +7 to +32
export const FarcasterAgentkitOptions = z
.object({
apiKey: z
.string()
.min(1, "The Neynar API key for Farcaster is required")
.describe("The Neynar API key for Farcaster"),
managedSigner: z
.string()
.min(1, "The Neynar Managed Signer UUID for Farcaster is required")
.describe("The Neynar Managed Signer UUID for Farcaster"),
})
.strip()
.describe("Options for initializing FarcasterAgentkit");

/**
* Schema for the environment variables required for FarcasterAgentkit.
*/
const EnvSchema = z.object({
NEYNAR_API_KEY: z
.string()
.min(1, "NEYNAR_API_KEY is required")
.describe("The Neynar API key for Farcaster"),
NEYNAR_MANAGED_SIGNER: z
.string()
.min(1, "NEYNAR_MANAGED_SIGNER is required")
.describe("The Neynar Managed Signer UUID for Farcaster"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are these configs injected into the action during run?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're not injected into the action (it's not needed, as it's an environment config), but just enforced and validated upon FarcasterAgentkit construction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants