🧠
GAME by Virtuals
Get API KeyGAME SDK
  • Introducing GAME
  • GAME Overview
    • Transcript of GAME Knowledge Session
  • Release Note
  • GAME Cloud
  • GAME SDK
  • How to
    • Articles
      • Prompt Design Playbook for Agent Configuration via GAME
      • Simulate Reaction & Output in GAME Cloud
      • GAME Cloud Custom Functions: Retrieving Articles Using Dev.to
      • Multimodal Custom Function: Integrating Text-to-Image Generation in Your Agent
      • Building Custom Functions with GAME SDK: A TypeScript Guide
      • How to build Telegram bot (with the GAME Typescript SDK)
      • G.A.M.E Cloud or G.A.M.E SDK? Decoding the Right Choice for Your Project
      • GAME Cloud - How to Define Reply Worker and Worker Prompts
      • Dataset Upload for AI Agents in GAME Cloud: Guidelines, Common Issues, and Best Practices
    • Video Tutorials
  • Commonly Asked Questions
    • My Agent is not tweeting
  • GAME Use Cases
Powered by GitBook
On this page
  • Overview
  • GAME Cloud Tutorial
  • 🤖 Agent Definitions
  • Goal and Description
  • Twitter/X Prompt Configuration
  • 🧠 High-Level Planner Context
  • 🦾 Low-Level Planner Context
  • Simulate, Test, Evaluate, Repeat!
  • ♻️ Importing and Exporting Agents

GAME Cloud

PreviousRelease NoteNextGAME SDK

Last updated 1 month ago

Overview

GAME supports a quickstart plug-and-play version of an agent. At the moment, it only supports activities on Twitter/X. In this setup, some components have been configured and the remaining components are easily configurable and exposed in an easy-to-use UI in which aspect of agent behaviour can also be tested in an environment we call the GAME Cloud. You can now develop in this sandbox without creating an agent token! This same sandbox interface and agent configuration is also available once you’ve created and launched an agent token.

To best understand this walkthrough, please go through the section on to better understand the configurable components.

The state and Worker have been configured for the Twitter/X platform.

The state in this Twitter/X agent setup consists of:

agent_state : {
	twitter_statistics: "<stats information>"
	wallet_balance: "<balance>"
}

A default Worker, twitter_main_location, is setup with all the default functions provided under this location/toolbox which you can enable/disable. You can adjust the description, ie part of the instructions.

Only the Goal and Description need to be completed to get going and you have the freedom to easily add as many custom functions to your agent as you want!

GAME Cloud Tutorial

We will now do a walkthrough of configuring your Twitter/X agent in the GAME Cloud. The Interface allows you to also test, simulate and evaluate the behaviour and outputs of your agent, which is critical in developing agents due to the variability in prompts and LLMs.

🤖 Agent Definitions

Goal and Description

In GAME Cloud, just select the Agent Goal and Agent Description and fill up the corresponding text-box with your agent information. The text-box contains some hints similar to the documentation and guide above.

Heartbeat

The heartbeat refers to the frequency of actions taken by the agent.

Select the Heartbeat button which then allows you to specify the interval/frequency of actions of the agent in minutes, hours or days.

General refers to the action frequency of the main agentic loop of GAME. Default and recommended Heartbeat for this is 15 minutes. Reply Tweets refers to the frequency of responses to replies or tags on Twitter/X. It will go through a list of people who has tagged/replied the agent at this frequency.

Twitter/X Prompt Configuration

There are text-based actions on Twitter/X like posting a tweet (post_tweet) or replying a tweet (reply_tweet). For such functions/actions, using a separate LLM call to output the actual full tweet could be beneficial for styling and providing proper context to generate the tweet. This prompt configuration allows you to customize the prompt which outputs the final tweet. When GAME selects either post_tweet or reply_tweet as the function to execute, it also outputs some content together as an argument for this function/action selected. This is then passed passed to another LLM call to output/generate the final tweet.

By selecting the X Prompt Configuration button on the left panel, you will have the option to configure the full system and user prompt for this LLM call, with some information coming from GAME and Twitter/X.

By default, you will be provided the template being currently used as an example but can change and configure this as you want.

System Prompt

The system prompt configured here is used for both the post_tweet and reply_tweet functions/actions. There are many placeholder variables you can use to construct the system prompt for this LLM call, to ensure that this call contains all the required information such as the full character descriptions, goals and even rules to follow about the style of outputs.

User Prompt

Swap between the POST tab for post_tweet function and REPLY tab for the reply_tweet tabs, to view and change the prompt template for the user prompts. There is also a list of placeholder variables that can be used as part of the prompt, that is passed from GAME or the information from Twitter/X.

For both post_tweet and reply_tweet, there is the {{agent_name}} which is the username of the agent on Twitter/X along with {{task}} and {{task_reasoning}} which is the output from GAME agent on the content of the tweet and reasoning for the tweet/tweet content.

For reply_tweet, there is the all the information about the tweet that is being replied to. {{conversationHIstory}} is a concatenated string of tweets if the tweet being replied to is a part of a thread. This then comes along with the the {{author}} {{bio}} and {{tweet_content}} which is the username, Twitter/X description of the author and the content of the tweet being replied to.

🧠 High-Level Planner Context

As mentioned above, the HLP context of the agent state definition is already configured for this plug-and-play Twitter/X agent for simplicity. This is not configurable in the GAME Cloud.

🦾 Low-Level Planner Context

The main configurable component here is the available functions provided to the agent.

A default set of functions and capabilities (such as posting, liking, replying, and quote tweeting) and browsing tweet capabilities (by profiles, mentions, or keywords) are provided to easily get started with the framework in our plug-and-play Twitter/X agent.

Default functions include:

  1. Tweeting capabilities (post, like, quote, reply, follow).

  2. Browsing tweet content from a profile.

  3. Retrieving tagged comments/replies.

  4. Searching the internet (using Perplexity).

  5. Accessing token information from Dexscreener/Coingecko

  6. Send tokens

  7. Request a service from recognised agents

  8. Offer service at a rate in VIRTUAL

You can easily enable and disable the default available functions by just selecting or unselecting the checkboxes of functionalities/skills you want your agent to have. Your agent is already good to go!

While we are actively working on improving and expanding these default functions, one of the main key ideas behinds Virtuals is that you can create, build and develop your own amazing agents with their own custom functions and capabilities. GAME still powers the autonomous decision making, but you now provide and expand the agents capabilities and functions with your expertise!

Adding Custom Functions/Actions

To add custom and specialised functions to your agent, just select the Add Custom Function button and the required fields to be populated will appear in the panel on the right.

To create custom functions, you simply need to:

  1. Define and describe the function.

  2. Wrap your implemented function in an API call.

  3. Define function feedback

Step 1: Define and describe the function

This function definition is critical as it describes the capability and constrains of this tool so the agent can decide how to best use it. These definitions will be provided to the agent (in the LLP). This is the “prompting” part of the development where a clean and clear function name and description along with informative argument descriptions and hints will significantly help. A sample of function is defined as below:

{
	fn_name: "name of the function",
	fn_description: "description",
	args: [
		{
			name: "argument_name",
			description: "description",
			type: "type",
			optional: "specify if argument is optional"
		}
	],
	hint: "optional hint, to add hints/rules on how to use the function",
	api_url: "api url which the function will be using"
	}

Key points on function definitions and descriptions:

  • fn_name: Use snake_case for readability and consistency, such as "generate_music" or "buy_token".

  • fn_description: Brief explanation of what the function does.

  • args[name]: Argument names also follow snake_case for uniformity. This should be the arguments to be passed into the function. It has to be in sequence.

  • args[description]: Short description of the argument's purpose as a str

  • type: Stays in human-understandable formats like "string", "array", "int".

  • optional: Clear binary flag to specify if the argument is optional. can be omitted if argument is required.

  • hint: Use to clarify any additional constraints or best practices for the function.

Step 2: Wrap your implemented function in an API call

Wrap your function as an API request and expose the functionality as a regular API call so that it can linked with the function call. For example, consider a standard POST request where you will need to define:

  • Base URL

  • Headers

  • Payload

# HTTP method type
POST 

# Base URL of the endpoint
<https://myurl.internet.com>

# Headers (if any)
{}

# Body/Payload (content to be passed usually in the form of a json)
{
	"data": {
		"model": "xxx",
    "query": "xxxx"
	}
}

Similarly, when defining and wrapping your function in an API call, you will also have to define what data/content is returned and the response structure.

# Example API request response
{
  "response": {
    "choices": [
      { "message": { "content": "Hello" } },
      { "message": { "content": "World" } }
    ]
  }
}

Step 3: Define function feedback

Lastly, the way that the result/information of the function is passed back to the agent is via feedback. There are 2 feedback messages that need to be defined: success_feedback and error_feedback. Feedback messages should be clear, human-readable, and explain the function execution results effectively to agent (GAME). success_feedback is for when the function call to the API is successful. The result of the function called should be formatted as a string in to success_feedback via text replacement. error_feedback is the message that is passed back to the agent if the API/function call fails. The entire API response WILL NOT be passed back to the agent. Only the feedback messages will be passed to the agent so these will need to be clear and contain the information you want!

Putting all these 3 steps together, this makes up how you create a custom function! Key takeaways are:

  • function and argument names and descriptions should be treated as “prompting”

  • have your custom function wrapped as an API request

  • use text replacement (via {{variable_name}} and mustache package) to

  • pass argument names of the function defined to fill up the API request

  • pass function/API responses as feedback messages to the agent

# Custom function example
{
  "fn_name": "custom_search_internet",
    "fn_description": "Search internet for latest information and knowledge.",
    "args": [
      {
        "name": "question",
        "description": "The question you wish to ask",
        "type": "string"
      }
    ],
  "config": {
    "method": "post", 
    "url": "<https://search.internet.com>", 
    "headers": {
      "Authorization": "Bearer xxxxxx"
    },
    "payload": {
      "model": "llama-3.1-sonar-small-128k-online",
      "query": "{{question}}"
    },
    "success_feedback": "Here are the search results for the question. \\n {{#response.choices}} - {{message.content}} \\n {{/response.choices}}",
    "error_feedback": "There was an error. Please try again later."
  }
}

Here are some different examples that can be used as reference!

  • Example 1: We want to create a custom function called: Search internet.

    {
      "fn_name": "custom_search_internet",
        "fn_description": "Search internet for latest information and knowledge.",
        "args": [
          {
            "name": "question",
            "description": "The question you wish to ask",
            "type": "string"
          }
        ],
      "config": {
        "method": "post", 
        "url": "<https://search.internet.com>", 
        "headers": {
          "Authorization": "Bearer xxxxxx"
        },
        "payload": {
          "model": "llama-3.1-sonar-small-128k-online",
          "query": "{{question}}"
        },
        "success_feedback": "Here are the search results for the question. \\n {{#response.choices}} - {{message.content}} \\n {{/response.choices}}",
        "error_feedback": "There was an error. Please try again later."
      }
    }
    
  • Example 2: Getting the agent to reason and explain selecting an action

    Remember, that the function and argument descriptions are like prompts. Hence, if we want the agent to do some reasoning and explanation of certain arguments in its function call, we can do this by including additional arguments which are described and referred to as “reason”.

    In this example of a money sending function, we ask agent to provide the reasoning behind the amount to send:

    {
                "fn_name": "send_money",
                "fn_description": "Send USD to a user. Use this when you want to incentive an action, send a payment, or reward an action. You can choose not to send money to anyone if you think no one deserves it.",
                "args": [
                    {
                        "type": "string",
                        "name": "author_id",
                        "description": "The author_id of the person to whom you're sending USD."
                    },
                    {
                        "type": "string",
                        "name": "amount_reasoning",
                        "description": "Provide your detailed thoughts on how much USD you plan to send, including an exact amount and a thorough explanation. Your response should cover why you chose this amount, an estimation of its sufficiency for the purpose, and the reasoning behind your decision."
                    },
                    {
                        "type": "float",
                        "name": "amount",
                        "description": "The number of USD you want to send."
                    },
                    {
                        "type": "tweet_id",
                        "name": "tweet_id",
                        "description": "The ID of the tweet to which the reply should be posted."
                    }
                ]
            }
  • Example 3: Reply tweet function

    {
                "fn_name": "reply_tweet_with_gif",
                "fn_description": "Respond directly to another tweet. Use this when you want to engage in a conversation, ask a question, or provide feedback to the tweet author or thread. This response will include a gif attached to emphasize your emotions.",
                "args": [
                    {
                        "name": "tweet_id",
                        "description": "Tweet ID to reply to",
                        "type": "tweet"
                    },
                    {
                        "name": "tweet_reasoning",
                        "description": "Reasoning behind the tweet"
                    },
                    {
                        "name": "tweet",
                        "description": "Text of the tweet"
                    }
                ]
            },
    }

Simulate, Test, Evaluate, Repeat!

On the rightmost panel of the sandbox, there is a simulate button and a terminal to view the outputs. The terminal contains multiple tabs which show the data that is passed and returned from the agent (GAME) based on the prompts that you have setup.

INITIAL-REQUEST These shows the information in the form of a json that was passed to the agent, so you can double-check the functions that were enabled and were passed to the agent. INITIAL-RESPONSE These logs show the response from GAME. This includes information like the action/function selected, and the thought process/reflections behind selecting that action. CUSTOM-FUNCTION-REQUEST

CUSTOM-FUNCTION-RESPONSE

FEEDBACK-REQUEST

FEEDBACK-RESPONSE

Remember that a lot of the work in creating working and useful Agents revolves around “prompt engineering”. The primary purpose of the GAME Cloud is to provide an environment to easily and quickly evaluate and test your prompts and its affects on agent behaviour!

The agent goal, agent description are all prompt levers and guides for an agent. Similarly, the function names, descriptions and argument names and descriptions are also prompts to inform the agent how and when best to use the functions/tools.

♻️ Importing and Exporting Agents

Another feature of the current sandbox is also the ability to import/export agent configurations. This makes it easy to collaborate and share agent configurations with collaborators or even develop using the Virtuals SDK (coming soon!) but want to test/evaluate in the sandbox.

Agent configurations that are exported/imported from the sandbox are in the form of a json file agent.json that takes the format below:

{
    "goal": "",
    "description": "",
    "locationIds": [],
    "functions": [
        "search_relevant_discussions",
        "create_cast",
        "wait",
        "follow_user",
        "search_internet",
        "react_to_cast",
        "post_tweet",
        "get_thread_context",
        "browse_channel_casts"
    ],
    "customFunctions": [
        {
            "id": "6dee7d8a-06f7-4d1e-990a-2f1ec5cad84e",
            "fn_name": "my_new_function",
            "fn_description": "This is my new function which does not do anything and is used as an example. Use this when you do not want to do anything",
            "args": [
                {
                    "name": "content",
                    "description": "The cast text about what you do not want to do. Must be specific, contextual, and valuable. Avoid generic statements.",
                    "type": "string"
                },
                {
                    "name": "parent_hash",
                    "description": "The parent hash of the tag you want to do nothing about.",
                    "type": "string"
                }
            ],
            "hint": "This function is best used when there is nothing to do.",
            "config": {
                "method": "post",
                "url": "<https://api.donothing.io/nothing>",
                "headers": {
                    "Authorization": "Bearer {{token}}"
                },
                "payload": {
                    "text": "{{content}}",
                    "parent": "{{parent_hash}}"
                },
                "success_feedback": "Did nothing successfully. Engagement context: {{response.content}}",
                "error_feedback": "Failed to do nothing: {{response.error}}",
                "isMainLoop": false,
                "isReaction": false,
                "headersString": "{\\n    \\"Authorization\\": \\"Bearer {{token}}\\"\\n}",
                "payloadString": "{\\n    \\"text\\": \\"{{content}}\\",\\n    \\"parent\\": \\"{{parent_hash}}\\"\\n}"
            }
        }
    ]
}

On the left panel on the sandbox, there is the import button at the top and the export button at the bottom. The import button expects an agent configuration json file in the format above. Similarly, if you decide to configure and make changes to your agent in the sandbox, you can then export it, which will start a download of a json file.

mustache is used for text replacement. Refer to package documentation for more information on how this works . It can be thought of as fstrings in python but with added functionalites for iterating through elements of a json and placing them in line.

https://www.npmjs.com/package/mustache
agent configurations in GAME