agents.json Python Implementation

repository·master·Indexed 23 days ago

https://github.com/wild-card-ai/agents-json

A Python implementation of the agents.json specification (v0.1.0), an open standard built on OpenAPI for defining structured contracts for AI agents. It introduces 'flows' and 'links' to enable LLMs to execute multi-step API workflows reliably. The library provides tools to load agents.json bundles, generate tool prompts and OpenAI-compatible tool definitions, and execute API calls with support for Basic, ApiKey, Bearer, and OAuth2 authentication.

Tokens
6.8K
Snippets
21
Records
36
Agent score
79%

What's inside agentsjson

  1. What is the agents.json Specification?

    master

    The agents.json Specification (current version 0.1.0) is an open specification designed to formally describe contracts for API and agent interactions. It is built on top of the OpenAPI standard but optimized for LLM consumption.

    While OpenAPI describes how endpoints work, agents.json adds structured contracts that help AI agents understand how to execute multi-step workflows. Key additions include:

    • Optimized Schema: Updated descriptions and added examples specifically for LLM argument generation and endpoint discovery.
    • Flows: Contracts consisting of one or more API calls that describe a specific outcome (e.g., instead of searching for an email and then replying, a single 'flow' can handle the entire task).
    • Links: Definitions of how different actions are stitched together, allowing agents to understand the sequence of operations required to achieve a goal.

    It is proposed that agents.json files be placed in /.well-known/agents.json for easy discovery by agents.

  2. Compare agents.json to MCP and llms.txt

    master

    agents.json vs. Model Context Protocol (MCP)

    • MCP is designed to be stateful, relying on persistent connections between clients and servers for exchanging context.
    • agents.json is stateless. The agent independently manages all context, making it compatible with existing agent architectures, RAG systems, pub/sub architectures, and serverless environments. Definitions are strongly typed via OpenAPI.

    agents.json vs. llms.txt

    • llms.txt is a standard for making website content readable for LLMs (improving retrieval/interpretation).
    • agents.json is designed for taking structured actions. It enables LLMs to execute multi-step workflows reliably.
  3. Get started with agents.json Quickstart Notebooks

    master

    To begin using agents.json with different authentication methods and service integrations, you can use the provided Jupyter notebooks. These notebooks demonstrate how to handle various auth patterns like API Keys, Bearer Tokens, and OAuth.

    AgentAuthNotebook
    ResendAPI Key./examples/resend.ipynb
    StripeBearer Token./examples/single.ipynb
    RootlyBearer Token./examples/rootly.ipynb
    Twitter + GiphyOAuth 1.0, API Key./examples/multiple.ipynb
    Resend + Hubspot + Google SheetsOAuth 2.0, API Key./examples/multiple-dynamic.ipynb
  4. Use Wildcard Bridge to run agents.json

    master

    Wildcard Bridge is a Python package that enables LLMs to load, parse, and execute agents.json files. It bridges the gap between an LLM's intent and the actual execution of API calls.

    Workflow:

    1. A developer connects their agent with an agents.json file.
    2. The agent selects the relevant chain(s) and populates arguments for a given task.
    3. Wildcard Bridge executes the chain(s).

    Supported Authentication: Bridge supports adding the following authentication types to requests:

    • Basic
    • ApiKey
    • Bearer
  5. Create a Google Sheets Agent

    master

    The GoogleSheetsAgent class encapsulates the logic for interacting with Google Sheets using agents.json. It manages three main lifecycle steps:

    1. setup_google_auth(): Sets up the Google Sheets API credentials using a provided JSON auth file.
    2. load_agents_json(agents_json_path): Loads the agents.json file and its corresponding openapi.yaml spec to build a Bundle object.
    3. execute_query(query, flow_hint): Takes a natural language query, uses an LLM (OpenAI) to select the appropriate API flows, and executes them against the Google Sheets API.

    To use the agent, initialize it with your auth_json_path and openai_api_key, then call the setup and load methods before executing queries.

    from openai import OpenAI
    from agentsjson.core.models.bundle import Bundle
    from agentsjson.core.executor import execute_flows
    import agentsjson.core as core
    from agentsjson.core import ToolFormat
    
    class GoogleSheetsAgent:
        def __init__(self, auth_json_path: str, openai_api_key: str):
            self.auth_json_path = auth_json_path
            self.openai_api_key = openai_api_key
            self.google_creds = None
            self.bundle = None
            self.flows = None
            self.openai_client = OpenAI(api_key=openai_api_key)
    
        def setup_google_auth(self) -> None:
            # ... implementation ...
            pass
    
        def load_agents_json(self, agents_json_path: str) -> None:
            # ... implementation ...
            pass
    
        def execute_query(self, query: str, flow_hint: Optional[List[str]] = None) -> Dict[str, Any]:
            # ... implementation ...
            pass
  6. Orchestrate multiple agents for complex tasks

    master

    For complex user requests that require multiple specialized agents, you can implement an orchestrator pattern. This involves:

    1. Defining a list of sub-agents with names and descriptions.
    2. Creating a system prompt that instructs the LLM to break down tasks and select the appropriate agent.
    3. Defining a tool (e.g., execute_agent) that the orchestrator can call to delegate tasks to sub-agents.
    4. Recursively calling the orchestrator until the task is complete or the LLM returns a 'STOP' signal.
    # Example structure for an orchestrator agent list
    agents_list = [
        {
            "name": "twitter_agent",
            "agent": twitter_agent,
            "description": "This agent makes requests to the Twitter API."
        },
        {
            "name": "giphy_agent",
            "agent": giphy_agent,
            "description": "This agent makes requests to the Giphy API."
        }
    ]
    
    # The orchestrator uses the agent descriptions to decide which tool to call
    # and passes natural language tasks to the sub-agents.
  7. Install dependencies for Google Sheets integration

    master

    To use agents.json with the Google Sheets API, you need to install the openai client and Google authentication libraries:

    %pip install openai google-auth-oauthlib google-auth-httplib2 google-auth
    %pip install openai google-auth-oauthlib google-auth-httplib2 google-auth
  8. Dynamically select tools using Wildcard API

    master

    You can implement a 'Wildcard Agent' that uses a specialized tool to search for the correct API flow based on a natural language task.

    1. Define a wildcard_tool for the LLM to call.
    2. The LLM calls wildcard_tool with a task description.
    3. Use the Wildcard Search API (https://queryfd.onrender.com/search) to find the matching flow_id and api_name using the task description.
    import requests
    import json
    
    # 1. Define the tool for the LLM
    wildcard_tool = {
        "type": "function",
        "function": {
            "name": "wildcard_tool",
            "description": "This function is responsible for calling the wildcard tool search API to find the right tool to use.",
            "parameters": {
                "type": "object",
                "properties": {
                    "task": {
                        "type": "string",
                        "description": "A brief description of the task to accomplish described precisely in natural language."
                    }
                },
                "required": ["task"],
            }
        }
    }
    
    # 2. After the LLM calls the tool, query the Wildcard API
    # (Assuming 'response' is the LLM output containing the tool call)
    args = json.loads(response.choices[0].message.tool_calls[0].function.arguments)
    task = args["task"]
    
    search_url = "https://queryfd.onrender.com/search"
    search_params = {
        "query": task,
        "collection_name": "YOUR_COLLECTION_NAME"
    }
    
    search_response = requests.get(search_url, params=search_params, headers={"x-api-key": "YOUR_WILDCARD_API_KEY"})
    search_results = search_response.json()
    
    # 3. Extract flow details
    flow_id = search_results["points"][0]["payload"]["flow"]["id"]
    api_name = search_results["points"][0]["payload"]["info"]["title"]
  9. Set up an agent Toolkit with authentication

    master

    When using multiple tools, create a toolkit mapping that associates tool IDs with their respective authentication configurations. You can then use a lookup function to retrieve the correct authentication for a specific agents_json instance based on its source ID.

    toolkit = {
        "resend": resend_auth,
    }
    
    def find_auth(agents_json):
        api = agents_json.sources[0].id
        return toolkit[api]
  10. Prepare flows for LLM prompts and tool definitions

    master

    To integrate agents.json flows into an LLM workflow, you need to perform two steps:

    1. Generate System Prompt Context: Use core.flows_prompt(flows) to convert the flow definitions into a text format suitable for a system prompt.
    2. Generate Tool Definitions: Use core.flows_tools(flows, format=...) to convert the flows into the specific tool/function calling format required by your LLM provider (e.g., ToolFormat.OPENAI).
  11. Execute API flows using an LLM response

    master

    To bridge the gap between an LLM's tool call and the actual API execution, follow these steps:

    1. Generate Tools: Use get_tools(agentsjson, format=ToolFormat.OPENAI) to convert the agents.json flows into the tool definitions required by the LLM (e.g., OpenAI).
    2. LLM Completion: Pass these tools to your LLM client (like openai.chat.completions.create).
    3. Execute: Pass the LLM's response to execute(), providing the agentsjson bundle, the response object, the tool format used, and the authentication configuration.