AgentToolProtocol


NameAgentToolProtocol JSON
Version 0.1.6 PyPI version JSON
download
home_pageNone
SummaryA Python SDK for registering, exposing, and serving your own Python functions as tools via the ATP platform. Supports secure OAuth2 flows, dynamic tool registration, and real-time tool invocation via WebSocket or HTTP.
upload_time2025-09-20 09:33:50
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseMIT
keywords agent toolkit chat sdk llm chatatp chatgpt ai agent frameworks websocket http api tools functions automation atp agent tool protocol atp sdk tool registration tool invocation tool serving toolkit registration toolkit invocation toolkit serving remote tool invocation remote tool serving remote tool registration remote toolkit invocation samuel obinna chimdi chatatp agent
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Agent Tool Protocol(ATP)

<p align="center">
  <img src="https://github.com/sam-14uel/Agent-Tool-Protocol/raw/main/assets/atp.png" alt="ATP Logo" />
</p>

<p align="center">
  <strong>
  A Python SDK for registering, exposing, and serving your own Python functions as tools via the ATP platform.
  Supports secure OAuth2 flows, dynamic tool registration, and real-time tool invocation via WebSocket.
  </strong>
</p>


---

## Table of Contents

- Installation
- Quick Start
- Class: ToolKitClient
  - Constructor
  - register_tool
  - start
  - stop
- Tool Function Requirements
- WebSocket Events
- Error Handling
- Examples
- Advanced Usage
- License

---

## Installation

```sh
pip install AgentToolProtocol
```

---

## Quick Start

```python
from atp_sdk.clients import ToolKitClient
import requests

client = ToolKitClient(
    api_key="YOUR_ATP_API_KEY",
    app_name="my_app"
)

@client.register_tool(
    function_name="hello_world",
    params=['name'],
    required_params=['name'],
    description="Returns a greeting.",
    auth_provider=None, auth_type=None, auth_with=None
)
def hello_world(**kwargs):
    return {"message": f"Hello, {kwargs.get('name', 'World')}!"}

client.start()
```

---

## Class: ToolKitClient

### Constructor

```python
ToolKitClient(
    api_key: str,
    app_name: str,
    base_url: str = "https://chatatp-backend.onrender.com"
)
```

**Parameters:**
- `api_key` (str): Your ATP API key.
- `app_name` (str): Name of your application.
- `base_url` (str, optional): ATP Server backend URL. Defaults to chatatp-backend.onrender.com.

---

### register_tool

Registers a Python function as a tool with the ATP platform.

```python
@client.register_tool(
    function_name: str,
    params: list[str],
    required_params: list[str],
    description: str,
    auth_provider: Optional[str],
    auth_type: Optional[str],
    auth_with: Optional[str]
)
def my_tool(**kwargs):
    ...
```

**Arguments:**
- `function_name`: Unique name for the tool.
- `params`: List of all parameter names.
- `required_params`: List of required parameter names.
- `description`: Human-readable description.
- `auth_provider`: Name of OAuth2 provider (e.g., "hubspot", "google"), or `None`.
- `auth_type`: Auth type (e.g., "OAuth2", "apiKey"), or `None`.
- `auth_with`: Name of the token parameter (e.g., "access_token", "api_key"), or `None`.

**Returns:**  
A decorator to wrap your function.

**Example:**

```python
@client.register_tool(
    function_name="create_company",
    params=['name', 'domain', 'industry'],
    required_params=['name', 'domain', 'industry'],
    description="Creates a company in HubSpot.",
    auth_provider="hubspot", auth_type="OAuth2", auth_with="access_token"
)
def create_company(**kwargs):
    access_token = kwargs.get('auth_token')
    url = "https://api.hubapi.com/crm/v3/objects/companies"
    headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
    data = {"properties": {
        "name": kwargs.get('name'),
        "domain": kwargs.get('domain'),
        "industry": kwargs.get('industry')
    }}
    response = requests.post(url, json=data, headers=headers)
    return response.json()
```

---

### start

Starts the WebSocket client and begins listening for tool requests.

```python
client.start()
```

- Keeps the main thread alive.
- Handles reconnections automatically.

---

### stop

Stops the WebSocket client and closes the connection.

```python
client.stop()
```

---

## Tool Function Requirements

- Must accept all parameters as `**kwargs`.
- If your tool requires authentication, expect `auth_token` in `kwargs`.
- Return a serializable object (dict, str, etc).

---

## WebSocket Events

### Tool Registration

Upon registration, your tool is announced to the ATP backend and available for invocation.

### Tool Invocation

When a tool request is received, your function is called with the provided parameters and (if needed) `auth_token`.

**Example incoming message:**
```json
{
  "message_type": "atp_tool_request",
  "payload": {
    "request_id": "uuid",
    "tool_name": "create_company",
    "params": {"name": "Acme", "domain": "acme.com", "industry": "Tech"},
    "auth_token": "ACCESS_TOKEN"
  }
}
```

---

## Error Handling

- If your function raises an exception, the error is caught and returned as:
  ```json
  {"error": "Error message"}
  ```
- If required parameters are missing, an error is returned.
- If `auth_token` is required but missing, an error is returned.

---

## Examples

### Minimal Tool

```python
@client.register_tool(
    function_name="echo",
    params=['text'],
    required_params=['text'],
    description="Echoes the input text.",
    auth_provider=None, auth_type=None, auth_with=None
)
def echo(**kwargs):
    return {"echo": kwargs.get('text')}
```

### Tool with OAuth2

```python
@client.register_tool(
    function_name="get_contacts",
    params=[],
    required_params=[],
    description="Fetches contacts from HubSpot.",
    auth_provider="hubspot", auth_type="OAuth2", auth_with="access_token"
)
def get_contacts(**kwargs):
    access_token = kwargs.get('auth_token')
    url = "https://api.hubapi.com/crm/v3/objects/contacts"
    headers = {"Authorization": f"Bearer {access_token}"}
    response = requests.get(url, headers=headers)
    return response.json()
```

### Tool with API Key

```python
@client.register_tool(
    function_name="get_contacts",
    params=[],
    required_params=[],
    description="Fetches contacts from HubSpot.",
    auth_provider="hubspot", auth_type="apiKey", auth_with="api_key"
)
def get_contacts(**kwargs):
    access_token = kwargs.get('auth_token')
    url = "https://api.hubapi.com/crm/v3/objects/contacts"
    headers = {"Authorization": f"Bearer {access_token}"}
    response = requests.get(url, headers=headers)
    return response.json()
```


---

## Class: LLMClient
The `LLMClient` lets you connect to the ATP Agent Server, retrieve toolkit context, and execute tools or workflows using JSON payloads—perfect for LLM-based agents.

### Constructor
```python
from atp_sdk.clients import LLMClient

llm_client = LLMClient(
    api_key="YOUR_ATP_API_KEY",
    protocol="ws",  # or "http"
    base_url="https://chatatp-backend.onrender.com/ws/v1/atp/llm-client/"
)
```
**Parameters:**
- `api_key` (str): Your ATP API key.
- `protocol` (str, optional): Protocol to use ("ws" or "http"). Defaults to "ws".
- `base_url` (str, optional): ATP server URL. Defaults to `https://chatatp-backend.onrender.com/ws/v1/atp/llm-client/`.

---

### get_toolkit_context
Retrieves the toolkit context and system instructions for a given toolkit and user prompt.
```python
context = llm_client.get_toolkit_context(
    toolkit_id="your_toolkit_id",
    provider="openai",  # or "anthropic" or "mistralai"
    user_prompt="What do you want to achieve?"
)
```
**Returns:**
A dictionary containing the toolkit context, including provider-specific tool schemas.

---

### call_tool
Executes a tool or workflow on the ATP server.
```python
response = llm_client.call_tool(
    toolkit_id="your_toolkit_id",
    json_response='{"function": "hello_world", "parameters": {"name": "Alice"}}',
    provider="openai",  # or "anthropic" or "mistralai"
    user_prompt="Say hello to Alice."
)
print(response)
```
**Arguments:**
- `toolkit_id`: Unique ID of the toolkit.
- `json_response`: JSON payload from an LLM containing the tool call.
- `provider`: The LLM provider (e.g., "openai", "anthropic", "mistralai").
- `user_prompt`: Additional user input to include in the execution.

---

## Request/Response Flow

### **1. LLM Requests Toolkit Context**
- The LLM (OpenAI, Anthropic, or Mistral) sends a request to the ATP server to get the toolkit context.
- The ATP server responds with a list of available tools and their schemas.

**Request:**
```json
{
  "type": "get_toolkit_context",
  "toolkit_id": "your_toolkit_id",
  "request_id": "uuid",
  "provider": "openai",
  "user_prompt": "What do you want to achieve?"
}
```

**Response:**
```json
{
  "type": "toolkit_context",
  "request_id": "uuid",
  "payload": {
    "toolkit_id": "your_toolkit_id",
    "toolkit_name": "Example Toolkit",
    "caption": "Example Caption",
    "provider": "openai",
    "tools": [
      {
        "type": "function",
        "name": "hello_world",
        "description": "Returns a greeting.",
        "parameters": {
          "type": "object",
          "properties": {
            "name": {"type": "string", "description": "Name to greet"}
          },
          "required": ["name"]
        }
      }
    ],
    "user_prompt": "What do you want to achieve?"
  }
}
```

---

### **2. LLM Generates Tool Calls**
- The LLM uses the toolkit context to generate tool calls.
- The LLM sends the tool calls to the ATP server for execution.

**Request:**
```json
{
  "type": "task_request",
  "toolkit_id": "your_toolkit_id",
  "request_id": "uuid",
  "payload": {
    "function": "hello_world",
    "parameters": {"name": "Alice"}
  },
  "provider": "openai",
  "user_prompt": "Say hello to Alice."
}
```

---

### **3. ATP Server Executes Tool**
- The ATP server receives the tool call and executes the corresponding tool.
- The ATP server sends the tool's response back to the LLM.

**Response:**
```json
{
  "type": "task_response",
  "request_id": "uuid",
  "payload": {
    "result": {"message": "Hello, Alice!"}
  }
}
```

---

## Using LLMClient with OpenAI, Anthropic, and Mistral AI

### OpenAI
```python
import openai
from atp_sdk.clients import LLMClient

openai_client = openai.OpenAI(api_key="YOUR_OPENAI_API_KEY")
llm_client = LLMClient(api_key="YOUR_ATP_API_KEY")

# Get toolkit context
context = llm_client.get_toolkit_context(
    toolkit_id="your_toolkit_id",
    provider="openai",
    user_prompt="Create a company and then list contacts."
)

# Use OpenAI to generate tool calls
response = openai_client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Create a company and then list contacts."}
    ],
    tools=context["tools"],
    tool_choice="auto"
)

# Extract tool calls
tool_calls = response.choices[0].message.tool_calls

# Loop through tool calls and execute each one
for tool_call in tool_calls:
    tool_call_json = {
        "function": tool_call.function.name,
        "parameters": tool_call.function.arguments
    }

    result = llm_client.call_tool(
        toolkit_id="your_toolkit_id",
        json_response=tool_call_json,
        provider="openai",
        user_prompt="Create a company and then list contacts."
    )

    print(f"Tool call result: {result}")
```

---

### Anthropic
```python
import anthropic
from atp_sdk.clients import LLMClient

anthropic_client = anthropic.Anthropic(api_key="YOUR_ANTHROPIC_API_KEY")
llm_client = LLMClient(api_key="YOUR_ATP_API_KEY")

# Get toolkit context
context = llm_client.get_toolkit_context(
    toolkit_id="your_toolkit_id",
    provider="anthropic",
    user_prompt="Create a company and then list contacts."
)

# Use Anthropic to generate tool calls
response = anthropic_client.messages.create(
    model="claude-3-opus-20240229",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Create a company and then list contacts."}
    ],
    tools=context["tools"]
)

# Extract tool calls
tool_calls = response.content

# Loop through tool calls and execute each one
for tool_call in tool_calls:
    tool_call_json = {
        "function": tool_call.name,
        "parameters": tool_call.input
    }

    result = llm_client.call_tool(
        toolkit_id="your_toolkit_id",
        json_response=tool_call_json,
        provider="anthropic",
        user_prompt="Create a company and then list contacts."
    )

    print(f"Tool call result: {result}")
```

---

### Mistral AI
```python
from mistralai.client import MistralClient
from atp_sdk.clients import LLMClient

mistral_client = MistralClient(api_key="YOUR_MISTRAL_API_KEY")
llm_client = LLMClient(api_key="YOUR_ATP_API_KEY")

# Get toolkit context
context = llm_client.get_toolkit_context(
    toolkit_id="your_toolkit_id",
    provider="mistralai",
    user_prompt="Create a company and then list contacts."
)

# Use Mistral to generate tool calls
response = mistral_client.chat(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Create a company and then list contacts."}],
    tools=context["tools"]
)

# Extract tool calls
tool_calls = response.choices[0].message.tool_calls

# Loop through tool calls and execute each one
for tool_call in tool_calls:
    tool_call_json = {
        "function": tool_call.function.name,
        "parameters": tool_call.function.arguments
    }

    result = llm_client.call_tool(
        toolkit_id="your_toolkit_id",
        json_response=tool_call_json,
        provider="mistralai",
        user_prompt="Create a company and then list contacts."
    )

    print(f"Tool call result: {result}")
```

---

## Handling Multi-Step Tool Calls
When the LLM generates multiple tool calls, loop through them and execute each one sequentially:

```python
# Loop through tool calls and execute each one
for tool_call in tool_calls:
    tool_call_json = {
        "function": tool_call.function.name,
        "parameters": tool_call.function.arguments
    }

    result = llm_client.call_tool(
        toolkit_id="your_toolkit_id",
        json_response=tool_call_json,
        provider="openai",  # or "anthropic" or "mistralai"
        user_prompt="Create a company and then list contacts."
    )

    print(f"Tool call result: {result}")
```

---

## Advanced Usage

### Custom Backend

```python
client = ToolKitClient(
    api_key="YOUR_API_KEY",
    app_name="my_app",
    base_url="https://your-backend.example.com"
)
```

### Multiple Tools

```python
@client.register_tool(...)
def tool1(**kwargs): ...

@client.register_tool(...)
def tool2(**kwargs): ...
```

---

## License

MIT License.  
See LICENSE for details.

---

## Feedback & Issues

For bug reports or feature requests, please open an issue on [GitHub](https://github.com/sam-14uel/Agent-Tool-Protocol).

---

**Happy coding! 🚀**

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "AgentToolProtocol",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "agent, toolkit, chat, sdk, llm, ChatATP, ChatGPT, AI Agent Frameworks, websocket, http, api, tools, functions, automation, ATP, Agent Tool Protocol, ATP SDK, tool registration, tool invocation, tool serving, toolkit registration, toolkit invocation, toolkit serving, remote tool invocation, remote tool serving, remote tool registration, remote toolkit invocation, Samuel Obinna Chimdi, ChatATP Agent",
    "author": null,
    "author_email": "Samuel Obinna Chimdi <sammyfirst6@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/38/aa/0064e66da12beedb99b03717462a245d6513b683795f27bfdf20f0ad6549/agenttoolprotocol-0.1.6.tar.gz",
    "platform": null,
    "description": "# Agent Tool Protocol(ATP)\r\n\r\n<p align=\"center\">\r\n  <img src=\"https://github.com/sam-14uel/Agent-Tool-Protocol/raw/main/assets/atp.png\" alt=\"ATP Logo\" />\r\n</p>\r\n\r\n<p align=\"center\">\r\n  <strong>\r\n  A Python SDK for registering, exposing, and serving your own Python functions as tools via the ATP platform.\r\n  Supports secure OAuth2 flows, dynamic tool registration, and real-time tool invocation via WebSocket.\r\n  </strong>\r\n</p>\r\n\r\n\r\n---\r\n\r\n## Table of Contents\r\n\r\n- Installation\r\n- Quick Start\r\n- Class: ToolKitClient\r\n  - Constructor\r\n  - register_tool\r\n  - start\r\n  - stop\r\n- Tool Function Requirements\r\n- WebSocket Events\r\n- Error Handling\r\n- Examples\r\n- Advanced Usage\r\n- License\r\n\r\n---\r\n\r\n## Installation\r\n\r\n```sh\r\npip install AgentToolProtocol\r\n```\r\n\r\n---\r\n\r\n## Quick Start\r\n\r\n```python\r\nfrom atp_sdk.clients import ToolKitClient\r\nimport requests\r\n\r\nclient = ToolKitClient(\r\n    api_key=\"YOUR_ATP_API_KEY\",\r\n    app_name=\"my_app\"\r\n)\r\n\r\n@client.register_tool(\r\n    function_name=\"hello_world\",\r\n    params=['name'],\r\n    required_params=['name'],\r\n    description=\"Returns a greeting.\",\r\n    auth_provider=None, auth_type=None, auth_with=None\r\n)\r\ndef hello_world(**kwargs):\r\n    return {\"message\": f\"Hello, {kwargs.get('name', 'World')}!\"}\r\n\r\nclient.start()\r\n```\r\n\r\n---\r\n\r\n## Class: ToolKitClient\r\n\r\n### Constructor\r\n\r\n```python\r\nToolKitClient(\r\n    api_key: str,\r\n    app_name: str,\r\n    base_url: str = \"https://chatatp-backend.onrender.com\"\r\n)\r\n```\r\n\r\n**Parameters:**\r\n- `api_key` (str): Your ATP API key.\r\n- `app_name` (str): Name of your application.\r\n- `base_url` (str, optional): ATP Server backend URL. Defaults to chatatp-backend.onrender.com.\r\n\r\n---\r\n\r\n### register_tool\r\n\r\nRegisters a Python function as a tool with the ATP platform.\r\n\r\n```python\r\n@client.register_tool(\r\n    function_name: str,\r\n    params: list[str],\r\n    required_params: list[str],\r\n    description: str,\r\n    auth_provider: Optional[str],\r\n    auth_type: Optional[str],\r\n    auth_with: Optional[str]\r\n)\r\ndef my_tool(**kwargs):\r\n    ...\r\n```\r\n\r\n**Arguments:**\r\n- `function_name`: Unique name for the tool.\r\n- `params`: List of all parameter names.\r\n- `required_params`: List of required parameter names.\r\n- `description`: Human-readable description.\r\n- `auth_provider`: Name of OAuth2 provider (e.g., \"hubspot\", \"google\"), or `None`.\r\n- `auth_type`: Auth type (e.g., \"OAuth2\", \"apiKey\"), or `None`.\r\n- `auth_with`: Name of the token parameter (e.g., \"access_token\", \"api_key\"), or `None`.\r\n\r\n**Returns:**  \r\nA decorator to wrap your function.\r\n\r\n**Example:**\r\n\r\n```python\r\n@client.register_tool(\r\n    function_name=\"create_company\",\r\n    params=['name', 'domain', 'industry'],\r\n    required_params=['name', 'domain', 'industry'],\r\n    description=\"Creates a company in HubSpot.\",\r\n    auth_provider=\"hubspot\", auth_type=\"OAuth2\", auth_with=\"access_token\"\r\n)\r\ndef create_company(**kwargs):\r\n    access_token = kwargs.get('auth_token')\r\n    url = \"https://api.hubapi.com/crm/v3/objects/companies\"\r\n    headers = {\"Authorization\": f\"Bearer {access_token}\", \"Content-Type\": \"application/json\"}\r\n    data = {\"properties\": {\r\n        \"name\": kwargs.get('name'),\r\n        \"domain\": kwargs.get('domain'),\r\n        \"industry\": kwargs.get('industry')\r\n    }}\r\n    response = requests.post(url, json=data, headers=headers)\r\n    return response.json()\r\n```\r\n\r\n---\r\n\r\n### start\r\n\r\nStarts the WebSocket client and begins listening for tool requests.\r\n\r\n```python\r\nclient.start()\r\n```\r\n\r\n- Keeps the main thread alive.\r\n- Handles reconnections automatically.\r\n\r\n---\r\n\r\n### stop\r\n\r\nStops the WebSocket client and closes the connection.\r\n\r\n```python\r\nclient.stop()\r\n```\r\n\r\n---\r\n\r\n## Tool Function Requirements\r\n\r\n- Must accept all parameters as `**kwargs`.\r\n- If your tool requires authentication, expect `auth_token` in `kwargs`.\r\n- Return a serializable object (dict, str, etc).\r\n\r\n---\r\n\r\n## WebSocket Events\r\n\r\n### Tool Registration\r\n\r\nUpon registration, your tool is announced to the ATP backend and available for invocation.\r\n\r\n### Tool Invocation\r\n\r\nWhen a tool request is received, your function is called with the provided parameters and (if needed) `auth_token`.\r\n\r\n**Example incoming message:**\r\n```json\r\n{\r\n  \"message_type\": \"atp_tool_request\",\r\n  \"payload\": {\r\n    \"request_id\": \"uuid\",\r\n    \"tool_name\": \"create_company\",\r\n    \"params\": {\"name\": \"Acme\", \"domain\": \"acme.com\", \"industry\": \"Tech\"},\r\n    \"auth_token\": \"ACCESS_TOKEN\"\r\n  }\r\n}\r\n```\r\n\r\n---\r\n\r\n## Error Handling\r\n\r\n- If your function raises an exception, the error is caught and returned as:\r\n  ```json\r\n  {\"error\": \"Error message\"}\r\n  ```\r\n- If required parameters are missing, an error is returned.\r\n- If `auth_token` is required but missing, an error is returned.\r\n\r\n---\r\n\r\n## Examples\r\n\r\n### Minimal Tool\r\n\r\n```python\r\n@client.register_tool(\r\n    function_name=\"echo\",\r\n    params=['text'],\r\n    required_params=['text'],\r\n    description=\"Echoes the input text.\",\r\n    auth_provider=None, auth_type=None, auth_with=None\r\n)\r\ndef echo(**kwargs):\r\n    return {\"echo\": kwargs.get('text')}\r\n```\r\n\r\n### Tool with OAuth2\r\n\r\n```python\r\n@client.register_tool(\r\n    function_name=\"get_contacts\",\r\n    params=[],\r\n    required_params=[],\r\n    description=\"Fetches contacts from HubSpot.\",\r\n    auth_provider=\"hubspot\", auth_type=\"OAuth2\", auth_with=\"access_token\"\r\n)\r\ndef get_contacts(**kwargs):\r\n    access_token = kwargs.get('auth_token')\r\n    url = \"https://api.hubapi.com/crm/v3/objects/contacts\"\r\n    headers = {\"Authorization\": f\"Bearer {access_token}\"}\r\n    response = requests.get(url, headers=headers)\r\n    return response.json()\r\n```\r\n\r\n### Tool with API Key\r\n\r\n```python\r\n@client.register_tool(\r\n    function_name=\"get_contacts\",\r\n    params=[],\r\n    required_params=[],\r\n    description=\"Fetches contacts from HubSpot.\",\r\n    auth_provider=\"hubspot\", auth_type=\"apiKey\", auth_with=\"api_key\"\r\n)\r\ndef get_contacts(**kwargs):\r\n    access_token = kwargs.get('auth_token')\r\n    url = \"https://api.hubapi.com/crm/v3/objects/contacts\"\r\n    headers = {\"Authorization\": f\"Bearer {access_token}\"}\r\n    response = requests.get(url, headers=headers)\r\n    return response.json()\r\n```\r\n\r\n\r\n---\r\n\r\n## Class: LLMClient\r\nThe `LLMClient` lets you connect to the ATP Agent Server, retrieve toolkit context, and execute tools or workflows using JSON payloads\u2014perfect for LLM-based agents.\r\n\r\n### Constructor\r\n```python\r\nfrom atp_sdk.clients import LLMClient\r\n\r\nllm_client = LLMClient(\r\n    api_key=\"YOUR_ATP_API_KEY\",\r\n    protocol=\"ws\",  # or \"http\"\r\n    base_url=\"https://chatatp-backend.onrender.com/ws/v1/atp/llm-client/\"\r\n)\r\n```\r\n**Parameters:**\r\n- `api_key` (str): Your ATP API key.\r\n- `protocol` (str, optional): Protocol to use (\"ws\" or \"http\"). Defaults to \"ws\".\r\n- `base_url` (str, optional): ATP server URL. Defaults to `https://chatatp-backend.onrender.com/ws/v1/atp/llm-client/`.\r\n\r\n---\r\n\r\n### get_toolkit_context\r\nRetrieves the toolkit context and system instructions for a given toolkit and user prompt.\r\n```python\r\ncontext = llm_client.get_toolkit_context(\r\n    toolkit_id=\"your_toolkit_id\",\r\n    provider=\"openai\",  # or \"anthropic\" or \"mistralai\"\r\n    user_prompt=\"What do you want to achieve?\"\r\n)\r\n```\r\n**Returns:**\r\nA dictionary containing the toolkit context, including provider-specific tool schemas.\r\n\r\n---\r\n\r\n### call_tool\r\nExecutes a tool or workflow on the ATP server.\r\n```python\r\nresponse = llm_client.call_tool(\r\n    toolkit_id=\"your_toolkit_id\",\r\n    json_response='{\"function\": \"hello_world\", \"parameters\": {\"name\": \"Alice\"}}',\r\n    provider=\"openai\",  # or \"anthropic\" or \"mistralai\"\r\n    user_prompt=\"Say hello to Alice.\"\r\n)\r\nprint(response)\r\n```\r\n**Arguments:**\r\n- `toolkit_id`: Unique ID of the toolkit.\r\n- `json_response`: JSON payload from an LLM containing the tool call.\r\n- `provider`: The LLM provider (e.g., \"openai\", \"anthropic\", \"mistralai\").\r\n- `user_prompt`: Additional user input to include in the execution.\r\n\r\n---\r\n\r\n## Request/Response Flow\r\n\r\n### **1. LLM Requests Toolkit Context**\r\n- The LLM (OpenAI, Anthropic, or Mistral) sends a request to the ATP server to get the toolkit context.\r\n- The ATP server responds with a list of available tools and their schemas.\r\n\r\n**Request:**\r\n```json\r\n{\r\n  \"type\": \"get_toolkit_context\",\r\n  \"toolkit_id\": \"your_toolkit_id\",\r\n  \"request_id\": \"uuid\",\r\n  \"provider\": \"openai\",\r\n  \"user_prompt\": \"What do you want to achieve?\"\r\n}\r\n```\r\n\r\n**Response:**\r\n```json\r\n{\r\n  \"type\": \"toolkit_context\",\r\n  \"request_id\": \"uuid\",\r\n  \"payload\": {\r\n    \"toolkit_id\": \"your_toolkit_id\",\r\n    \"toolkit_name\": \"Example Toolkit\",\r\n    \"caption\": \"Example Caption\",\r\n    \"provider\": \"openai\",\r\n    \"tools\": [\r\n      {\r\n        \"type\": \"function\",\r\n        \"name\": \"hello_world\",\r\n        \"description\": \"Returns a greeting.\",\r\n        \"parameters\": {\r\n          \"type\": \"object\",\r\n          \"properties\": {\r\n            \"name\": {\"type\": \"string\", \"description\": \"Name to greet\"}\r\n          },\r\n          \"required\": [\"name\"]\r\n        }\r\n      }\r\n    ],\r\n    \"user_prompt\": \"What do you want to achieve?\"\r\n  }\r\n}\r\n```\r\n\r\n---\r\n\r\n### **2. LLM Generates Tool Calls**\r\n- The LLM uses the toolkit context to generate tool calls.\r\n- The LLM sends the tool calls to the ATP server for execution.\r\n\r\n**Request:**\r\n```json\r\n{\r\n  \"type\": \"task_request\",\r\n  \"toolkit_id\": \"your_toolkit_id\",\r\n  \"request_id\": \"uuid\",\r\n  \"payload\": {\r\n    \"function\": \"hello_world\",\r\n    \"parameters\": {\"name\": \"Alice\"}\r\n  },\r\n  \"provider\": \"openai\",\r\n  \"user_prompt\": \"Say hello to Alice.\"\r\n}\r\n```\r\n\r\n---\r\n\r\n### **3. ATP Server Executes Tool**\r\n- The ATP server receives the tool call and executes the corresponding tool.\r\n- The ATP server sends the tool's response back to the LLM.\r\n\r\n**Response:**\r\n```json\r\n{\r\n  \"type\": \"task_response\",\r\n  \"request_id\": \"uuid\",\r\n  \"payload\": {\r\n    \"result\": {\"message\": \"Hello, Alice!\"}\r\n  }\r\n}\r\n```\r\n\r\n---\r\n\r\n## Using LLMClient with OpenAI, Anthropic, and Mistral AI\r\n\r\n### OpenAI\r\n```python\r\nimport openai\r\nfrom atp_sdk.clients import LLMClient\r\n\r\nopenai_client = openai.OpenAI(api_key=\"YOUR_OPENAI_API_KEY\")\r\nllm_client = LLMClient(api_key=\"YOUR_ATP_API_KEY\")\r\n\r\n# Get toolkit context\r\ncontext = llm_client.get_toolkit_context(\r\n    toolkit_id=\"your_toolkit_id\",\r\n    provider=\"openai\",\r\n    user_prompt=\"Create a company and then list contacts.\"\r\n)\r\n\r\n# Use OpenAI to generate tool calls\r\nresponse = openai_client.chat.completions.create(\r\n    model=\"gpt-4o\",\r\n    messages=[\r\n        {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\r\n        {\"role\": \"user\", \"content\": \"Create a company and then list contacts.\"}\r\n    ],\r\n    tools=context[\"tools\"],\r\n    tool_choice=\"auto\"\r\n)\r\n\r\n# Extract tool calls\r\ntool_calls = response.choices[0].message.tool_calls\r\n\r\n# Loop through tool calls and execute each one\r\nfor tool_call in tool_calls:\r\n    tool_call_json = {\r\n        \"function\": tool_call.function.name,\r\n        \"parameters\": tool_call.function.arguments\r\n    }\r\n\r\n    result = llm_client.call_tool(\r\n        toolkit_id=\"your_toolkit_id\",\r\n        json_response=tool_call_json,\r\n        provider=\"openai\",\r\n        user_prompt=\"Create a company and then list contacts.\"\r\n    )\r\n\r\n    print(f\"Tool call result: {result}\")\r\n```\r\n\r\n---\r\n\r\n### Anthropic\r\n```python\r\nimport anthropic\r\nfrom atp_sdk.clients import LLMClient\r\n\r\nanthropic_client = anthropic.Anthropic(api_key=\"YOUR_ANTHROPIC_API_KEY\")\r\nllm_client = LLMClient(api_key=\"YOUR_ATP_API_KEY\")\r\n\r\n# Get toolkit context\r\ncontext = llm_client.get_toolkit_context(\r\n    toolkit_id=\"your_toolkit_id\",\r\n    provider=\"anthropic\",\r\n    user_prompt=\"Create a company and then list contacts.\"\r\n)\r\n\r\n# Use Anthropic to generate tool calls\r\nresponse = anthropic_client.messages.create(\r\n    model=\"claude-3-opus-20240229\",\r\n    max_tokens=1024,\r\n    messages=[\r\n        {\"role\": \"user\", \"content\": \"Create a company and then list contacts.\"}\r\n    ],\r\n    tools=context[\"tools\"]\r\n)\r\n\r\n# Extract tool calls\r\ntool_calls = response.content\r\n\r\n# Loop through tool calls and execute each one\r\nfor tool_call in tool_calls:\r\n    tool_call_json = {\r\n        \"function\": tool_call.name,\r\n        \"parameters\": tool_call.input\r\n    }\r\n\r\n    result = llm_client.call_tool(\r\n        toolkit_id=\"your_toolkit_id\",\r\n        json_response=tool_call_json,\r\n        provider=\"anthropic\",\r\n        user_prompt=\"Create a company and then list contacts.\"\r\n    )\r\n\r\n    print(f\"Tool call result: {result}\")\r\n```\r\n\r\n---\r\n\r\n### Mistral AI\r\n```python\r\nfrom mistralai.client import MistralClient\r\nfrom atp_sdk.clients import LLMClient\r\n\r\nmistral_client = MistralClient(api_key=\"YOUR_MISTRAL_API_KEY\")\r\nllm_client = LLMClient(api_key=\"YOUR_ATP_API_KEY\")\r\n\r\n# Get toolkit context\r\ncontext = llm_client.get_toolkit_context(\r\n    toolkit_id=\"your_toolkit_id\",\r\n    provider=\"mistralai\",\r\n    user_prompt=\"Create a company and then list contacts.\"\r\n)\r\n\r\n# Use Mistral to generate tool calls\r\nresponse = mistral_client.chat(\r\n    model=\"mistral-large-latest\",\r\n    messages=[{\"role\": \"user\", \"content\": \"Create a company and then list contacts.\"}],\r\n    tools=context[\"tools\"]\r\n)\r\n\r\n# Extract tool calls\r\ntool_calls = response.choices[0].message.tool_calls\r\n\r\n# Loop through tool calls and execute each one\r\nfor tool_call in tool_calls:\r\n    tool_call_json = {\r\n        \"function\": tool_call.function.name,\r\n        \"parameters\": tool_call.function.arguments\r\n    }\r\n\r\n    result = llm_client.call_tool(\r\n        toolkit_id=\"your_toolkit_id\",\r\n        json_response=tool_call_json,\r\n        provider=\"mistralai\",\r\n        user_prompt=\"Create a company and then list contacts.\"\r\n    )\r\n\r\n    print(f\"Tool call result: {result}\")\r\n```\r\n\r\n---\r\n\r\n## Handling Multi-Step Tool Calls\r\nWhen the LLM generates multiple tool calls, loop through them and execute each one sequentially:\r\n\r\n```python\r\n# Loop through tool calls and execute each one\r\nfor tool_call in tool_calls:\r\n    tool_call_json = {\r\n        \"function\": tool_call.function.name,\r\n        \"parameters\": tool_call.function.arguments\r\n    }\r\n\r\n    result = llm_client.call_tool(\r\n        toolkit_id=\"your_toolkit_id\",\r\n        json_response=tool_call_json,\r\n        provider=\"openai\",  # or \"anthropic\" or \"mistralai\"\r\n        user_prompt=\"Create a company and then list contacts.\"\r\n    )\r\n\r\n    print(f\"Tool call result: {result}\")\r\n```\r\n\r\n---\r\n\r\n## Advanced Usage\r\n\r\n### Custom Backend\r\n\r\n```python\r\nclient = ToolKitClient(\r\n    api_key=\"YOUR_API_KEY\",\r\n    app_name=\"my_app\",\r\n    base_url=\"https://your-backend.example.com\"\r\n)\r\n```\r\n\r\n### Multiple Tools\r\n\r\n```python\r\n@client.register_tool(...)\r\ndef tool1(**kwargs): ...\r\n\r\n@client.register_tool(...)\r\ndef tool2(**kwargs): ...\r\n```\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT License.  \r\nSee LICENSE for details.\r\n\r\n---\r\n\r\n## Feedback & Issues\r\n\r\nFor bug reports or feature requests, please open an issue on [GitHub](https://github.com/sam-14uel/Agent-Tool-Protocol).\r\n\r\n---\r\n\r\n**Happy coding! \ud83d\ude80**\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Python SDK for registering, exposing, and serving your own Python functions as tools via the ATP platform. Supports secure OAuth2 flows, dynamic tool registration, and real-time tool invocation via WebSocket or HTTP.",
    "version": "0.1.6",
    "project_urls": {
        "Documentation": "https://github.com/agent-tool-protocol/python-sdk/blob/main/README.md",
        "Homepage": "https://github.com/agent-tool-protocol/python-sdk",
        "Issues": "https://github.com/agent-tool-protocol/python-sdk/issues",
        "Repository": "https://github.com/agent-tool-protocol/python-sdk"
    },
    "split_keywords": [
        "agent",
        " toolkit",
        " chat",
        " sdk",
        " llm",
        " chatatp",
        " chatgpt",
        " ai agent frameworks",
        " websocket",
        " http",
        " api",
        " tools",
        " functions",
        " automation",
        " atp",
        " agent tool protocol",
        " atp sdk",
        " tool registration",
        " tool invocation",
        " tool serving",
        " toolkit registration",
        " toolkit invocation",
        " toolkit serving",
        " remote tool invocation",
        " remote tool serving",
        " remote tool registration",
        " remote toolkit invocation",
        " samuel obinna chimdi",
        " chatatp agent"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bbe9c4ce9979ef0f979a3e3013713b325d0b9c50aee4b0f6e2c65502c43ec34f",
                "md5": "daac2072082ae9a19912284d6f86c239",
                "sha256": "484e8e12d0d758dbf1c69c41c3e283b63e7318715ed30a2b543cfd2da0312ecd"
            },
            "downloads": -1,
            "filename": "agenttoolprotocol-0.1.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "daac2072082ae9a19912284d6f86c239",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 16579,
            "upload_time": "2025-09-20T09:33:43",
            "upload_time_iso_8601": "2025-09-20T09:33:43.275867Z",
            "url": "https://files.pythonhosted.org/packages/bb/e9/c4ce9979ef0f979a3e3013713b325d0b9c50aee4b0f6e2c65502c43ec34f/agenttoolprotocol-0.1.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "38aa0064e66da12beedb99b03717462a245d6513b683795f27bfdf20f0ad6549",
                "md5": "e866ff967d6a528818c0aecaba9207ad",
                "sha256": "e51aa171fa766e313ccd97aef9c58bb48a5bb79cf572e4d94f9d4f3d7802b318"
            },
            "downloads": -1,
            "filename": "agenttoolprotocol-0.1.6.tar.gz",
            "has_sig": false,
            "md5_digest": "e866ff967d6a528818c0aecaba9207ad",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 17071,
            "upload_time": "2025-09-20T09:33:50",
            "upload_time_iso_8601": "2025-09-20T09:33:50.178884Z",
            "url": "https://files.pythonhosted.org/packages/38/aa/0064e66da12beedb99b03717462a245d6513b683795f27bfdf20f0ad6549/agenttoolprotocol-0.1.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-20 09:33:50",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "agent-tool-protocol",
    "github_project": "python-sdk",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "agenttoolprotocol"
}
        
Elapsed time: 0.81307s