|
| 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()} |
0 commit comments