# 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"
)
```
---
### 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",
user_prompt="What do you want to achieve?"
)
```
---
### call_tool
Executes a tool or workflow on the ATP server.
```python
response = llm_client.call_tool(
toolkit_id="your_toolkit_id",
json_response=json.dumps({
"function": "hello_world",
"parameters": {"name": "Alice"},
"task_title": "Say hello",
"execution_type": "remote"
})
)
print(response)
```
---
## Example: Using LLMClient with OpenAI, Anthropic, and Mistral AI
You can use any LLM to generate the JSON workflow, then execute each step with `LLMClient`.
### 1. OpenAI (GPT-4o)
```python
import openai
from atp_sdk.clients import LLMClient
client = openai.OpenAI(api_key="YOUR_OPENAI_API_KEY")
llm_client = LLMClient(api_key="YOUR_ATP_API_KEY")
# Get toolkit context and system prompt
context = llm_client.get_toolkit_context(toolkit_id="your_toolkit_id", user_prompt="Create a company and then list contacts.")
# Use OpenAI to generate the workflow JSON
response = client.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": context},
{"role": "user", "content": "Create a company and then list contacts."}
]
)
workflow_json = response.choices[0].message.content
# Parse and execute each workflow step
import json
workflow = json.loads(workflow_json)
if "workflows" in workflow:
results = []
for step in workflow["workflows"]:
result = llm_client.call_tool(
toolkit_id="your_toolkit_id",
json_response=json.dumps(step)
)
results.append(result)
else:
result = llm_client.call_tool(
toolkit_id="your_toolkit_id",
json_response=workflow_json
)
```
### 2. Anthropic (Claude)
```python
import anthropic
from atp_sdk.clients import LLMClient
llm_client = LLMClient(api_key="YOUR_ATP_API_KEY")
context = llm_client.get_toolkit_context(toolkit_id="your_toolkit_id", user_prompt="...")
client = anthropic.Anthropic(api_key="YOUR_ANTHROPIC_API_KEY")
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
messages=[
{"role": "user", "content": context}
]
)
workflow_json = response.content[0].text
# Execute as above
```
### 3. Mistral AI
```python
from mistralai.client import MistralClient
from atp_sdk.clients import LLMClient
llm_client = LLMClient(api_key="YOUR_ATP_API_KEY")
context = llm_client.get_toolkit_context(toolkit_id="your_toolkit_id", user_prompt="...")
client = MistralClient(api_key="YOUR_MISTRAL_API_KEY")
response = client.chat(
model="mistral-large-latest",
messages=[{"role": "user", "content": context}]
)
workflow_json = response.choices[0].message.content
# Execute as above
```
---
## Handling Multi-Step Workflows
When the LLM returns a workflow with multiple steps:
```python
import json
workflow = json.loads(workflow_json)
if "workflows" in workflow:
results = []
for step in workflow["workflows"]:
result = llm_client.call_tool(
toolkit_id="your_toolkit_id",
json_response=json.dumps(step)
)
results.append(result)
else:
result = llm_client.call_tool(
toolkit_id="your_toolkit_id",
json_response=workflow_json
)
```
- For each step, call `llm_client.call_toolkit` with the step JSON.
- Collect and process results as needed.
- If a step has `"depends_on"`, you can pass outputs from previous steps as needed.
---
## Example: Full Workflow
```python
from atp_sdk.clients import LLMClient
import openai
import json
llm_client = LLMClient(api_key="YOUR_ATP_API_KEY")
context = llm_client.get_toolkit_context(toolkit_id="your_toolkit_id", user_prompt="...")
response = openai.ChatCompletion.create(
model="gpt-4o",
messages=[
{"role": "system", "content": context},
{"role": "user", "content": "Do a multi-step task."}
]
)
workflow_json = response.choices[0].message.content
workflow = json.loads(workflow_json)
results = []
if "workflows" in workflow:
for step in workflow["workflows"]:
result = llm_client.call_tool(
toolkit_id="your_toolkit_id",
json_response=json.dumps(step)
)
results.append(result)
else:
result = llm_client.call_tool(
toolkit_id="your_toolkit_id",
json_response=workflow_json
)
results.append(result)
print(results)
```
---
**Tip:**
Always ensure the LLM returns valid JSON as described in the toolkit context instructions.
---
## 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",
"author": null,
"author_email": "Samuel Obinna Chimdi <sammyfirst6@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/b9/ba/5389428b92b815689b929beef29b1f25e99697e2ee123fcaa3231d6ea656/agenttoolprotocol-0.1.4.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\n\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\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)\r\n```\r\n\r\n---\r\n\r\n### get_toolkit_context\r\n\r\nRetrieves the toolkit context and system instructions for a given toolkit and user prompt.\r\n\r\n```python\r\ncontext = llm_client.get_toolkit_context(\r\n toolkit_id=\"your_toolkit_id\",\r\n user_prompt=\"What do you want to achieve?\"\r\n)\r\n```\r\n\r\n---\r\n\r\n### call_tool\r\n\r\nExecutes a tool or workflow on the ATP server.\r\n\r\n```python\r\nresponse = llm_client.call_tool(\r\n toolkit_id=\"your_toolkit_id\",\r\n json_response=json.dumps({\r\n \"function\": \"hello_world\",\r\n \"parameters\": {\"name\": \"Alice\"},\r\n \"task_title\": \"Say hello\",\r\n \"execution_type\": \"remote\"\r\n })\r\n)\r\nprint(response)\r\n```\r\n\r\n---\r\n\r\n## Example: Using LLMClient with OpenAI, Anthropic, and Mistral AI\r\n\r\nYou can use any LLM to generate the JSON workflow, then execute each step with `LLMClient`.\r\n\r\n### 1. OpenAI (GPT-4o)\r\n\r\n```python\r\nimport openai\r\nfrom atp_sdk.clients import LLMClient\r\n\r\nclient = 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 and system prompt\r\ncontext = llm_client.get_toolkit_context(toolkit_id=\"your_toolkit_id\", user_prompt=\"Create a company and then list contacts.\")\r\n\r\n# Use OpenAI to generate the workflow JSON\r\nresponse = client.completions.create(\r\n model=\"gpt-4o\",\r\n messages=[\r\n {\"role\": \"system\", \"content\": context},\r\n {\"role\": \"user\", \"content\": \"Create a company and then list contacts.\"}\r\n ]\r\n)\r\nworkflow_json = response.choices[0].message.content\r\n\r\n# Parse and execute each workflow step\r\nimport json\r\nworkflow = json.loads(workflow_json)\r\nif \"workflows\" in workflow:\r\n results = []\r\n for step in workflow[\"workflows\"]:\r\n result = llm_client.call_tool(\r\n toolkit_id=\"your_toolkit_id\",\r\n json_response=json.dumps(step)\r\n )\r\n results.append(result)\r\nelse:\r\n result = llm_client.call_tool(\r\n toolkit_id=\"your_toolkit_id\",\r\n json_response=workflow_json\r\n )\r\n```\r\n\r\n### 2. Anthropic (Claude)\r\n\r\n```python\r\nimport anthropic\r\nfrom atp_sdk.clients import LLMClient\r\n\r\nllm_client = LLMClient(api_key=\"YOUR_ATP_API_KEY\")\r\ncontext = llm_client.get_toolkit_context(toolkit_id=\"your_toolkit_id\", user_prompt=\"...\")\r\n\r\nclient = anthropic.Anthropic(api_key=\"YOUR_ANTHROPIC_API_KEY\")\r\nresponse = client.messages.create(\r\n model=\"claude-3-opus-20240229\",\r\n max_tokens=1024,\r\n messages=[\r\n {\"role\": \"user\", \"content\": context}\r\n ]\r\n)\r\nworkflow_json = response.content[0].text\r\n\r\n# Execute as above\r\n```\r\n\r\n### 3. Mistral AI\r\n\r\n```python\r\nfrom mistralai.client import MistralClient\r\nfrom atp_sdk.clients import LLMClient\r\n\r\nllm_client = LLMClient(api_key=\"YOUR_ATP_API_KEY\")\r\ncontext = llm_client.get_toolkit_context(toolkit_id=\"your_toolkit_id\", user_prompt=\"...\")\r\n\r\nclient = MistralClient(api_key=\"YOUR_MISTRAL_API_KEY\")\r\nresponse = client.chat(\r\n model=\"mistral-large-latest\",\r\n messages=[{\"role\": \"user\", \"content\": context}]\r\n)\r\nworkflow_json = response.choices[0].message.content\r\n\r\n# Execute as above\r\n```\r\n\r\n---\r\n\r\n## Handling Multi-Step Workflows\r\n\r\nWhen the LLM returns a workflow with multiple steps:\r\n\r\n```python\r\nimport json\r\n\r\nworkflow = json.loads(workflow_json)\r\nif \"workflows\" in workflow:\r\n results = []\r\n for step in workflow[\"workflows\"]:\r\n result = llm_client.call_tool(\r\n toolkit_id=\"your_toolkit_id\",\r\n json_response=json.dumps(step)\r\n )\r\n results.append(result)\r\nelse:\r\n result = llm_client.call_tool(\r\n toolkit_id=\"your_toolkit_id\",\r\n json_response=workflow_json\r\n )\r\n```\r\n\r\n- For each step, call `llm_client.call_toolkit` with the step JSON.\r\n- Collect and process results as needed.\r\n- If a step has `\"depends_on\"`, you can pass outputs from previous steps as needed.\r\n\r\n---\r\n\r\n## Example: Full Workflow\r\n\r\n```python\r\nfrom atp_sdk.clients import LLMClient\r\nimport openai\r\nimport json\r\n\r\nllm_client = LLMClient(api_key=\"YOUR_ATP_API_KEY\")\r\ncontext = llm_client.get_toolkit_context(toolkit_id=\"your_toolkit_id\", user_prompt=\"...\")\r\n\r\nresponse = openai.ChatCompletion.create(\r\n model=\"gpt-4o\",\r\n messages=[\r\n {\"role\": \"system\", \"content\": context},\r\n {\"role\": \"user\", \"content\": \"Do a multi-step task.\"}\r\n ]\r\n)\r\nworkflow_json = response.choices[0].message.content\r\nworkflow = json.loads(workflow_json)\r\n\r\nresults = []\r\nif \"workflows\" in workflow:\r\n for step in workflow[\"workflows\"]:\r\n result = llm_client.call_tool(\r\n toolkit_id=\"your_toolkit_id\",\r\n json_response=json.dumps(step)\r\n )\r\n results.append(result)\r\nelse:\r\n result = llm_client.call_tool(\r\n toolkit_id=\"your_toolkit_id\",\r\n json_response=workflow_json\r\n )\r\n results.append(result)\r\n\r\nprint(results)\r\n```\r\n\r\n---\r\n\r\n**Tip:** \r\nAlways ensure the LLM returns valid JSON as described in the toolkit context instructions.\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": "Agent Tool Protocol SDK",
"version": "0.1.4",
"project_urls": {
"Homepage": "https://github.com/sam-14uel/Agent-Tool-Protocol",
"Repository": "https://github.com/sam-14uel/Agent-Tool-Protocol"
},
"split_keywords": [
"agent",
" toolkit",
" chat",
" sdk",
" llm",
" chatatp",
" chatgpt",
" ai agent frameworks"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "eadb2bf82c805ef7f027324b95f9a9107a2140b51af4a589168499a15373e8ff",
"md5": "e729a2d5a5612b3cc7e3aa9da191f918",
"sha256": "1c9d21958ebca3517ed5fd499a46a62b693656741b359d6d7a28700116bc3947"
},
"downloads": -1,
"filename": "agenttoolprotocol-0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e729a2d5a5612b3cc7e3aa9da191f918",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 11253,
"upload_time": "2025-08-06T00:07:47",
"upload_time_iso_8601": "2025-08-06T00:07:47.389339Z",
"url": "https://files.pythonhosted.org/packages/ea/db/2bf82c805ef7f027324b95f9a9107a2140b51af4a589168499a15373e8ff/agenttoolprotocol-0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b9ba5389428b92b815689b929beef29b1f25e99697e2ee123fcaa3231d6ea656",
"md5": "96ce7fd2297fcf95109097f3a2b5833c",
"sha256": "b00e2b155e45b1a19d60aa6a2f66246ebb78294603c148897f272b718e4fe5d6"
},
"downloads": -1,
"filename": "agenttoolprotocol-0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "96ce7fd2297fcf95109097f3a2b5833c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 11020,
"upload_time": "2025-08-06T00:07:51",
"upload_time_iso_8601": "2025-08-06T00:07:51.386570Z",
"url": "https://files.pythonhosted.org/packages/b9/ba/5389428b92b815689b929beef29b1f25e99697e2ee123fcaa3231d6ea656/agenttoolprotocol-0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-06 00:07:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "sam-14uel",
"github_project": "Agent-Tool-Protocol",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "agenttoolprotocol"
}