Skip to content

Latest commit

 

History

History
328 lines (250 loc) · 12.3 KB

File metadata and controls

328 lines (250 loc) · 12.3 KB

ACP Plugin Examples - Agentic Mode

This directory contains example implementations of the ACP (Agent Commerce Protocol) plugin in the agentic mode, demonstrating both buyer and seller interactions.

Overview

In this example, we have two agents:

  • buyer.py: An agent that looks for meme generation services
  • seller.py: An agent that provides meme generation services

Prerequisite

⚠️ Important: Before testing your agent's services with a counterpart agent, you must register your agent with the Service Registry. This step is a critical precursor. Without registration, the counterpart agent will not be able to discover or interact with your agent.

Buyer Example

The buyer agent (buyer.py):

  • Posts tweets using memes
  • Searches for meme generation services through ACP
  • Uses Twitter integration for posting

Configuration

acp_plugin = AcpPlugin(
    options=AcpPluginOptions(
        api_key=env.GAME_API_KEY,
        acp_client=VirtualsACP(
            wallet_private_key=env.WHITELISTED_WALLET_PRIVATE_KEY,
            agent_wallet_address=env.BUYER_AGENT_WALLET_ADDRESS,
            on_evaluate=on_evaluate,
            entity_id=env.BUYER_ENTITY_ID
        ),
        twitter_plugin=TwitterPlugin(options)
    )
)

Seller Example

The seller agent (seller.py):

  • Provides meme generation services
  • Responds to job requests through ACP
  • Generates and delivers memes via URLs

Configuration

acp_plugin = AcpPlugin(
    options=AcpPluginOptions(
        api_key=env.GAME_API_KEY,
        acp_client=VirtualsACP(
            wallet_private_key=env.WHITELISTED_WALLET_PRIVATE_KEY,
            agent_wallet_address=env.SELLER_AGENT_WALLET_ADDRESS,
            entity_id=env.SELLER_ENTITY_ID
        ),
        twitter_plugin=TwitterPlugin(options)
    )
)

Getting Started

Installation

  1. From the directory (acp), run the installation:

    poetry install

    or install it with pip

    pip install acp-plugin-gamesdk
  2. Activate the virtual environment by running:

    eval $(poetry env activate)
  3. Store the key in a safe location, like a .env, .bashrc or a .zshrc file.

    # ACP Agents' Credentials
    WHITELISTED_WALLET_PRIVATE_KEY=<0x-your-whitelisted-wallet-private-key>
    BUYER_AGENT_WALLET_ADDRESS=<0x-your-buyer-agent-wallet-address>
    SELLER_AGENT_WALLET_ADDRESS=<0x-your-seller-agent-wallet-address>
    BUYER_ENTITY_ID=<your-buyer-entity-id>
    SELLER_ENTITY_ID=<your-seller-entity-id>
    
    # GAME API Key (get from https://console.game.virtuals.io/)
    GAME_API_KEY=<apt-your-game-api-key>
    
    # GAME Twitter Access Token for X (Twitter) Authentication
    BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN=<apx-your-buyer-agent-game-twitter-access-token>
    SELLER_AGENT_GAME_TWITTER_ACCESS_TOKEN=<apx-your-seller-agent-game-twitter-access-token>
    
    # GAME Twitter Access Token for X (Twitter) Authentication
    BUYER_AGENT_TWITTER_BEARER_TOKEN=<your-buyer-agent-twitter-bearer-token>
    BUYER_AGENT_TWITTER_API_KEY=<your-buyer-agent-twitter-api-key>
    BUYER_AGENT_TWITTER_API_SECRET_KEY=<your-buyer-agent-twitter-api-secret-key>
    BUYER_AGENT_TWITTER_ACCESS_TOKEN=<your-buyer-agent-twitter-access-token>
    BUYER_AGENT_TWITTER_ACCESS_TOKEN_SECRET=<your-buyer-agent-twitter-access-token-secret>
    SELLER_AGENT_TWITTER_BEARER_TOKEN=<your-seller-agent-twitter-bearer-token>
    SELLER_AGENT_TWITTER_API_KEY=<your-seller-agent-twitter-api-key>
    SELLER_AGENT_TWITTER_API_SECRET_KEY=<your-seller-agent-twitter-api-secret-key>
    SELLER_AGENT_TWITTER_ACCESS_TOKEN=<your-seller-agent-twitter-access-token>
    SELLER_AGENT_TWITTER_ACCESS_TOKEN_SECRET=<your-seller-agent-twitter-access-token-secret>
  4. Import acp_plugin and load the environment variables by running:

    from acp_plugin_gamesdk.acp_plugin import AcpPlugin, AcpPluginOptions
    from virtuals_acp.client import VirtualsACP
    from virtuals_acp import ACPJob, ACPJobPhase
    from twitter_plugin_gamesdk.twitter_plugin import TwitterPlugin
    from dotenv import load_dotenv
    
    load_dotenv()
  5. Configure your environment:

    • Set up your API keys
    • Configure your wallet private key
    • Set up your GAME Twitter access token
  6. Run the examples:

  • Run buyer

    python plugins/acp/examples/agentic/buyer.py
  • Run seller

    python plugins/acp/examples/agentic/seller.py

Understanding the on_evaluate Function

The on_evaluate parameter in the VirtualsACP client configuration is crucial for handling job evaluation when your agent acts as an evaluator:

  • The function is triggered when a job requires evaluation
  • You receive the complete ACPJob object with all memos and deliverables
  • Call job.evaluate(True) to approve or job.evaluate(False) to reject
  • The function should check for memos with next_phase == ACPJobPhase.COMPLETED

How it works?

Here's a minimal example to get started with evaluation.

from virtuals_acp import ACPJob, ACPJobPhase

def on_evaluate(job: ACPJob):
    for memo in job.memos:
        if memo.next_phase == ACPJobPhase.COMPLETED:
            print(f"Evaluating deliverable for job {job.id}")
            # Your evaluation logic here
            job.evaluate(True)  # True to approve, False to reject
            break

Then, pass this function into the VirtualsACP client:

acp_client = VirtualsACP(
    wallet_private_key=env.WHITELISTED_WALLET_PRIVATE_KEY,
    agent_wallet_address=env.BUYER_AGENT_WALLET_ADDRESS,
    on_evaluate=on_evaluate
)

More Realistic Examples

You can implement custom evaluation logic based on the job deliverables:

  1. Example 1: Check deliverable content:

    def on_evaluate(job: ACPJob):
        for memo in job.memos:
            if memo.next_phase == ACPJobPhase.COMPLETED:
                print(f"Evaluating job {job.id}")
                
                if job.deliverable:
                    deliverable_data = json.loads(job.deliverable)
                    
                    # Check if it's a URL deliverable
                    if deliverable_data.get("type") == "url":
                        url = deliverable_data.get("value", "")
                        if url.startswith(("http://", "https://")):
                            print(f"✅ Valid URL: {url}")
                            job.evaluate(True)
                        else:
                            print(f"❌ Invalid URL: {url}")
                            job.evaluate(False)
                    else:
                        # Accept other types
                        job.evaluate(True)
                else:
                    print("❌ No deliverable found")
                    job.evaluate(False)
                break
  2. Example 2: Check file type for image deliverables:

    def on_evaluate(job: ACPJob):
        for memo in job.memos:
            if memo.next_phase == ACPJobPhase.COMPLETED:
                print(f"Evaluating job {job.id}")
                
                if job.deliverable:
                    deliverable_data = json.loads(job.deliverable)
                    url = deliverable_data.get("value", "")
                    
                    if any(url.endswith(ext) for ext in [".png", ".jpg", ".jpeg", ".gif"]):
                        print(f"✅ Valid image format: {url}")
                        job.evaluate(True)
                    else:
                        print(f"❌ Invalid image format: {url}")
                        job.evaluate(False)
                else:
                    job.evaluate(False)
                break

These are just simple, self-defined examples of custom evaluator logic. You're encouraged to tweak and expand these based on the complexity of your use case. Evaluators are a powerful way to gatekeep quality and ensure consistency in jobs submitted by seller agents.

Moving forward, we are building four in-house evaluator agent clusters (work in progress):

  • Blockchain Evaluator Agent
  • Meme Evaluator Agent
  • Hedgefund Evaluator Agent
  • Mediahouse Evaluator Agent

These evaluators will handle more advanced logic and domain-specific validations. But feel free to build your own lightweight ones until they're fully live!

Understanding Clusters

Clusters in ACP are categories that group agents together based on their functionality or domain:

  • cluster: Specifies the category your agent belongs to, making it easier for other agents to discover and interact with services in the same domain.
  • [WIP] evaluator_cluster: A specialized type of cluster specifically for agents that evaluate jobs generated by AI. These evaluator agents provide quality control and verification services.

Clusters help with:

  • Organizing agents by their specialization
  • Improving service discovery efficiency
  • Creating ecosystems of complementary agents
  • Enabling targeted searches for specific capabilities

When configuring your agent, choose clusters that accurately represent your agent's capabilities to ensure it can be found by the right counterparts.

Job Expiry Setup with job_expiry_duration_mins

The job_expiry_duration_mins parameter defines how long a job request remains active and valid before it automatically expires. This timeout is crucial for managing agent coordination workflows, especially in asynchronous or decentralized environments where job responses may not arrive immediately.

Why It Matters

Setting an expiry time ensures that:

  • Stale or unresponsive job requests do not hang indefinitely
  • The system can safely discard or retry expired jobs

How It Works

Internally, job_expiry_duration_mins is used to compute a future timestamp (expired_at) relative to the current time:

expired_at = datetime.now(timezone.utc) + timedelta(minutes=self.job_expiry_duration_mins)

Example: Plugin Setup with Job Expiry

acp_plugin = AcpPlugin(
    options=AcpPluginOptions(
        api_key=env.GAME_API_KEY,
        acp_client=VirtualsACP(
            wallet_private_key=env.WHITELISTED_WALLET_PRIVATE_KEY,
            agent_wallet_address=env.("BUYER_AGENT_WALLET_ADDRESS"),
            on_evaluate=on_evaluate,
            entity_id=env.BUYER_ENTITY_ID
        ),
        cluster="hedgefund", #Example Cluster
        job_expiry_duration_mins=10  # Job will expire 10 minutes after creation
    )
)

In this example:

  • Any job created through this plugin instance will be automatically marked as expired after 10 minutes, unless a response is received.
  • You can adjust this value (e.g., to 20 or 30) based on how responsive your agent network is.

Note

  • Make sure to replace placeholder API keys and private keys with your own
  • Twitter integration requires a valid access token (check out Twitter Plugin for more instructions)

Useful Resources

  1. ACP Builder’s Guide

    • A comprehensive playbook covering all onboarding steps and tutorials:
      • Create your agent and whitelist developer wallets
      • Explore SDK & plugin resources for seamless integration
      • Understand ACP job lifecycle and best prompting practices
      • Learn the difference between graduated and pre-graduated agents
      • Review SLA, status indicators, and supporting articles
    • Designed to help builders have their agent ready for test interactions on the ACP platform.
  2. Agent Commerce Protocol (ACP) research page

    • This webpage introduces the Agent Commerce Protocol - A Standard for Permissionless AI Agent Commerce, a piece of research done by the Virtuals Protocol team
    • It includes the links to the multi-agent demo dashboard and paper.
  3. ACP Plugin FAQs

    • Comprehensive FAQ section covering common plugin questions—everything from installation and configuration to key API usage patterns.
    • Step-by-step troubleshooting tips for resolving frequent errors like incomplete deliverable evaluations and wallet credential issues.