Skip to content

Commit 7c2445c

Browse files
committed
Add ZohoDeskAgent
1 parent da54dfb commit 7c2445c

File tree

5 files changed

+208
-0
lines changed

5 files changed

+208
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Zoho Desk Agent
2+
3+
This agent allows you to interact with the Zoho Desk API to manage tickets, contacts, and other Zoho Desk resources.
4+
5+
## Requirements
6+
7+
- Zoho Desk API access token
8+
- Zoho Desk organization ID
9+
- Patchwork framework
10+
11+
## Usage
12+
13+
The ZohoDeskAgent can be used to:
14+
- Retrieve ticket information
15+
- Create new tickets
16+
- Update existing tickets
17+
- Manage contacts
18+
- Query departments and other Zoho Desk resources
19+
20+
## Input Parameters
21+
22+
Required:
23+
- `zoho_access_token`: Your Zoho Desk API access token
24+
- `org_id`: Zoho Desk organization ID (required for all API calls)
25+
- `user_prompt`: The prompt template to use for the agent
26+
- `prompt_value`: Dictionary of values to render in the user prompt template
27+
28+
Optional:
29+
- `max_agent_calls`: Maximum number of agent calls (default: 1)
30+
- `system_prompt`: Custom system prompt
31+
- `example_json`: Example JSON for the agent
32+
- LLM API keys (one of the following):
33+
- `openai_api_key`
34+
- `anthropic_api_key`
35+
- `google_api_key`
36+
37+
## Example
38+
39+
```python
40+
from patchwork.steps.ZohoDeskAgent import ZohoDeskAgent
41+
42+
# Initialize the agent
43+
agent = ZohoDeskAgent({
44+
"zoho_access_token": "your_zoho_access_token",
45+
"org_id": "your_organization_id",
46+
"user_prompt": "Get information about ticket {{ticket_id}}",
47+
"prompt_value": {"ticket_id": "12345"},
48+
"anthropic_api_key": "your_anthropic_api_key",
49+
"max_agent_calls": 3
50+
})
51+
52+
# Run the agent
53+
result = agent.run()
54+
print(result)
55+
```
56+
57+
## API Endpoints
58+
59+
The agent can interact with various Zoho Desk API endpoints, including:
60+
61+
- `GET /tickets` - List tickets
62+
- `GET /tickets/{ticketId}` - Get ticket details
63+
- `POST /tickets` - Create a ticket
64+
- `PUT /tickets/{ticketId}` - Update a ticket
65+
- `GET /departments` - List departments
66+
- `GET /contacts` - List contacts
67+
- `GET /contacts/{contactId}` - Get contact details
68+
- `POST /contacts` - Create a contact
69+
- `GET /contacts/{contactId}/tickets` - List tickets by contact
70+
71+
## Query Parameters
72+
73+
Common query parameters for listing resources:
74+
- `include`: Additional information to include (e.g., 'products', 'departments', 'team', 'isRead', 'assignee')
75+
- `from`: Index number to start fetching from
76+
- `limit`: Number of items to fetch (range: 1-100)
77+
- `sortBy`: Sort by a specific attribute (e.g., 'createdTime', 'modifiedTime')
78+
79+
For more information about the Zoho Desk API, refer to the [official documentation](https://desk.zoho.com/DeskAPIDocument).
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from patchwork.common.client.llm.aio import AioLlmClient
2+
from patchwork.common.multiturn_strategy.agentic_strategy_v2 import (
3+
AgentConfig,
4+
AgenticStrategyV2,
5+
)
6+
from patchwork.common.tools.api_tool import APIRequestTool
7+
from patchwork.common.utils.utils import mustache_render
8+
from patchwork.step import Step
9+
10+
from .typed import ZohoDeskAgentInputs, ZohoDeskAgentOutputs
11+
12+
13+
class ZohoDeskAgent(Step, input_class=ZohoDeskAgentInputs, output_class=ZohoDeskAgentOutputs):
14+
def __init__(self, inputs: dict):
15+
super().__init__(inputs)
16+
17+
if not inputs.get("zoho_access_token"):
18+
raise ValueError("zoho_access_token is required")
19+
if not inputs.get("user_prompt"):
20+
raise ValueError("user_prompt is required")
21+
if not inputs.get("org_id"):
22+
raise ValueError("org_id is required for Zoho Desk API calls")
23+
24+
# Configure conversation limit
25+
self.conversation_limit = int(inputs.get("max_agent_calls", 1))
26+
27+
# Prepare system prompt with Zoho Desk context
28+
system_prompt = inputs.get(
29+
"system_prompt",
30+
"Please summarise the conversation given and provide the result in the structure that is asked of you.",
31+
)
32+
33+
# Set up headers for Zoho Desk API
34+
self.headers = {
35+
"Authorization": f"Zoho-oauthtoken {inputs.get('zoho_access_token')}",
36+
"orgId": inputs.get("org_id"),
37+
"Content-Type": "application/json",
38+
"Accept": "application/json",
39+
}
40+
41+
llm_client = AioLlmClient.create_aio_client(inputs)
42+
43+
# Configure agentic strategy with Zoho Desk-specific context
44+
self.agentic_strategy = AgenticStrategyV2(
45+
model="claude-3-7-sonnet-latest",
46+
llm_client=llm_client,
47+
system_prompt_template=system_prompt,
48+
template_data={},
49+
user_prompt_template=mustache_render(inputs.get("user_prompt"), inputs.get("prompt_value")),
50+
agent_configs=[
51+
AgentConfig(
52+
name="Zoho Desk Assistant",
53+
model="claude-3-7-sonnet-latest",
54+
tool_set=dict(
55+
make_api_request=APIRequestTool(
56+
headers=self.headers,
57+
)
58+
),
59+
system_prompt="""\
60+
You are a senior software developer helping users interact with Zoho Desk via the Zoho Desk API.
61+
Your goal is to retrieve, create, or modify tickets, contacts, and other Zoho Desk resources.
62+
Use the `make_api_request` tool to interact with the Zoho Desk API.
63+
Skip the headers for the API requests as they are already provided.
64+
65+
The base URL for the Zoho Desk API is https://desk.zoho.com/api/v1
66+
67+
For modifying or creating data, the data should be a JSON string.
68+
When you have the result of the information user requested, return the response of the final result tool as is.
69+
70+
Here are some common Zoho Desk API endpoints:
71+
- GET /tickets - List tickets
72+
- GET /tickets/{ticketId} - Get ticket details
73+
- POST /tickets - Create a ticket
74+
- PUT /tickets/{ticketId} - Update a ticket
75+
- GET /departments - List departments
76+
- GET /contacts - List contacts
77+
- GET /contacts/{contactId} - Get contact details
78+
- POST /contacts - Create a contact
79+
- GET /contacts/{contactId}/tickets - List tickets by contact
80+
81+
Additional query parameters:
82+
- include: Additional information related to tickets. Values allowed are: 'products', 'departments', 'team', 'isRead', and 'assignee'. Multiple values can be comma-separated.
83+
- from: Index number to start fetching from
84+
- limit: Number of items to fetch (range: 1-100)
85+
- sortBy: Sort by a specific attribute like 'createdTime' or 'modifiedTime'. Prefix with '-' for descending order.
86+
87+
The orgId is already included in the headers for all API calls.
88+
""",
89+
)
90+
],
91+
example_json=inputs.get("example_json"),
92+
)
93+
94+
def run(self) -> dict:
95+
# Execute the agentic strategy
96+
result = self.agentic_strategy.execute(limit=self.conversation_limit)
97+
98+
# Return results with usage information
99+
return {**result, **self.agentic_strategy.usage()}

patchwork/steps/ZohoDeskAgent/__init__.py

Whitespace-only changes.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from typing_extensions import Annotated, Any, Dict, List, Optional, TypedDict
2+
3+
from patchwork.common.utils.step_typing import StepTypeConfig
4+
5+
6+
class __ZohoDeskAgentInputsRequired(TypedDict):
7+
zoho_access_token: str
8+
user_prompt: str
9+
prompt_value: Dict[str, Any]
10+
org_id: str
11+
12+
13+
class ZohoDeskAgentInputs(__ZohoDeskAgentInputsRequired, total=False):
14+
max_agent_calls: int
15+
openai_api_key: Annotated[str, StepTypeConfig(or_op=["google_api_key", "anthropic_api_key"])]
16+
anthropic_api_key: Annotated[str, StepTypeConfig(or_op=["google_api_key", "openai_api_key"])]
17+
google_api_key: Annotated[str, StepTypeConfig(or_op=["openai_api_key", "anthropic_api_key"])]
18+
19+
# Prompt and strategy configuration
20+
system_prompt: Optional[str]
21+
example_json: Optional[Dict]
22+
23+
24+
class ZohoDeskAgentOutputs(TypedDict):
25+
conversation_history: List[Dict]
26+
tool_records: List[Dict]
27+
request_tokens: int
28+
response_tokens: int

patchwork/steps/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
from patchwork.steps.SimplifiedLLM.SimplifiedLLM import SimplifiedLLM
5353
from patchwork.steps.SimplifiedLLMOnce.SimplifiedLLMOnce import SimplifiedLLMOnce
5454
from patchwork.steps.SlackMessage.SlackMessage import SlackMessage
55+
from patchwork.steps.ZohoDeskAgent.ZohoDeskAgent import ZohoDeskAgent
5556

5657
# Compatibility Aliases
5758
JoinListPB = JoinList
@@ -112,4 +113,5 @@
112113
"GetTypescriptTypeInfo",
113114
"BrowserUse",
114115
"ManageEngineAgent",
116+
"ZohoDeskAgent",
115117
]

0 commit comments

Comments
 (0)