HighRoller commited on
Commit
02b5c87
·
verified ·
1 Parent(s): 61c0457

Upload 14 files

Browse files
Files changed (14) hide show
  1. Seed_Dataset.csv +263 -0
  2. Updated_API_list.json +1 -0
  3. all_apis.py +383 -0
  4. api_json_to_doc.py +24 -0
  5. app.py +203 -0
  6. hal_check.py +377 -0
  7. imports.py +20 -0
  8. mem_check.py +12 -0
  9. pipelines.py +201 -0
  10. prompt_templates.py +70 -0
  11. prompts.py +150 -0
  12. requirements.txt +11 -0
  13. retrieval.py +46 -0
  14. update_api_toolset.py +169 -0
Seed_Dataset.csv ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ QUERY,REASONING
2
+ Query:Summarize issues similar to don:core:dvrv-us-1:devo/0:issue/1,"We need to summarize issues similar to don:core:dvrv-us-1:devo/0:issue/1 which we can see is an ID (a unique identifier for an issue) so we will first call the ""get_similar_work_items"" API with argument name : ""work_id"" and argument_value: ""don:core:dvrv-us-1:devo/0:issue/1"" since we need to get similar issues.
3
+
4
+ Next, we will call the ""summarize_objects"" API with argument_name: ""objects"" and argument_value: ""$$PREV[0]"" since we need to then summarize the issues and we can refer the value of the ith chain using ""$$PREV[0]"". Therefore, the answer is: [(tool_name: get_similar_work_items, argument_name: work_id, argument_value: don:core:dvrv-us-1:devo/0:issue/1), (tool_name: summarize_objects), (argument_name: objects, argument_value: $$PREV[0]),]"
5
+ Query: Prioritize my P0 issues and add them to the current sprint,"To prioritize your P0 issues and add them to the current sprint, we need to perform the following steps using the provided APIs:
6
+
7
+ 1. **Identify the User:** First, we need to identify who ""my"" refers to in the query. We will use the `who_am_i` API to get the ID of the current user.
8
+ - Tool Name: `who_am_i`
9
+ - Arguments: []
10
+
11
+ 2. **List P0 Issues Owned by the User:** Next, we need to list all the P0 issues that are owned by the user. We will use the `works_list` API with three arguments:
12
+ - Tool Name: `works_list`
13
+ - Arguments:
14
+ - (argument_name: `owned_by`, argument_value: `$$PREV[0]`)
15
+ - (argument_name: `issue.priority`, argument_value: `['p0']`)
16
+ - (argument_name: `type`, argument_value: `['issue']`)
17
+
18
+ 3. **Prioritize the Retrieved Issues:** Once we have the list of P0 issues, we need to prioritize them. We will use the `prioritize_objects` API with the list of issues obtained from the previous step.
19
+ - Tool Name: `prioritize_objects`
20
+ - Arguments:
21
+ - (argument_name: `objects`, argument_value: `$$PREV[1]`)
22
+
23
+ 4. **Get Current Sprint ID:** To add these issues to the current sprint, we first need to know the ID of the current sprint. We will use the `get_sprint_id` API.
24
+ - Tool Name: `get_sprint_id`
25
+ - Arguments: []
26
+
27
+ 5. **Add Prioritized Issues to the Current Sprint:** Finally, we will use the `add_work_items_to_sprint` API to add the prioritized P0 issues to the current sprint. We will use two arguments: the list of prioritized work IDs and the sprint ID.
28
+ - Tool Name: `add_work_items_to_sprint`
29
+ - Arguments:
30
+ - (argument_name: `work_ids`, argument_value: `$$PREV[2]`)
31
+ - (argument_name: `sprint_id`, argument_value: `$$PREV[3]`)
32
+
33
+ Therefore, the answer is:
34
+ - [(tool_name: `who_am_i`, arguments: []),
35
+ - (tool_name: `works_list`, arguments: [(argument_name: `owned_by`, argument_value: `$$PREV[0]`), (argument_name: `issue.priority`, argument_value: `['p0']`), (argument_name: `type`, argument_value: `['issue']`)]),
36
+ - (tool_name: `prioritize_objects`, arguments: [(argument_name: `objects`, argument_value: `$$PREV[1]`)]),
37
+ - (tool_name: `get_sprint_id`, arguments: []),
38
+ - (tool_name: `add_work_items_to_sprint`, arguments: [(argument_name: `work_ids`, argument_value: `$$PREV[2]`), (argument_name: `sprint_id`, argument_value: `$$PREV[3]`)])]"
39
+ "Query: Summarize high severity tickets from the customer UltimateCustomer
40
+ ","To summarize high severity tickets from the customer named ""UltimateCustomer,"" we need to follow these steps:
41
+
42
+ 1. First, we need to identify the ID of the object (in this case, the customer ""UltimateCustomer"") using the `search_object_by_name` API. This is because we need the ID to filter tickets related to this customer. So, we will call `search_object_by_name` with the argument `(argument_name: query, argument_value: UltimateCustomer)`.
43
+
44
+ 2. Next, we will use the `works_list` API to retrieve the list of high severity tickets related to ""UltimateCustomer."" For this, we need three arguments:
45
+ - `(argument_name: ticket.severity, argument_value: high)` to filter for high severity tickets,
46
+ - `(argument_name: ticket.source_channel, argument_value: $$PREV[0])` to filter tickets related to ""UltimateCustomer"" (using the ID retrieved from the previous step),
47
+ - `(argument_name: type, argument_value: ticket)` to ensure we are only retrieving tickets.
48
+
49
+ 3. Finally, we need to summarize the retrieved tickets. We do this by calling the `summarize_objects` API with the argument `(argument_name: objects, argument_value: $$PREV[1])`, where `$$PREV[1]` refers to the list of high severity tickets related to ""UltimateCustomer.""
50
+
51
+ Therefore, the answer is:
52
+ - [(tool_name: search_object_by_name, arguments= [(argument_name: query, argument_value: UltimateCustomer)]),
53
+ - (tool_name: works_list, arguments= [(argument_name: ticket.severity, argument_value: high), (argument_name: ticket.source_channel, argument_value: $$PREV[0]), (argument_name: type, argument_value: ticket)]),
54
+ - (tool_name: summarize_objects, arguments= [(argument_name: objects, argument_value: $$PREV[1])])]
55
+ "
56
+ "Query: What are my all issues in the triage stage under part FEAT-123? Summarize them.
57
+
58
+ ","Since the query has specified that we have find the issues of the person sending the query, we need to call the ""whoami"" API first to identify the person. After that we need to call the ""works_list"" API to get all the issues with three arguments here since we: 1) have to get the tools in triage stage, 2) identify tools under part ""FEAT-123"", 3) Identify the matching tools that are owned by the person asking the query. Therefore, the three arguments are (with the format: (argument_name, argument_value)): 1) (stage.name, triage) 2) (applies_to_part, FEAT-123) 3) (owned_by, $$PREV[0]). Finally, we will call the ""summarize_objects"" tool with argument_name: ""objects"" and argument_value: '""$$PREV[1]"" since we are tasked to summarize all these issues. Thus the answer is : [(tool_name: whoami, arguments =[ ], (tool_name: works_list, arguments= ([argument_name: stage.name, argument_value: triage], [argument_name:applies_to_part, argument_value: FEAT-123], [argument_name: owned_by, argument_value: $$PREV[0]]),(tool_name: summarize_objects, (arguments = ([argument_name: objects, argument_value: $$PREV[0]),])]"
59
+ "Query:List all high severity tickets coming in from slack from customer Cust123 and generate a summary of them.
60
+ ","To solve this task, we need to perform the following steps:
61
+
62
+ 1. **Find the ID of the customer ""Cust123""**: Since we need to filter tickets by a specific customer, we first need to identify the ID of ""Cust123"". We can do this by calling the `search_object_by_name` API with the argument `(query, Cust123)`.
63
+
64
+ 2. **List all high severity tickets from Slack related to ""Cust123""**: After obtaining the customer ID, we need to list the tickets. For this, we call the `works_list` API with three arguments: `(ticket.severity, high)`, `(ticket.source_channel, slack)`, and `(reported_by, $$PREV[0])`. Here, `$$PREV[0]` refers to the output of the first API call, which is the ID of ""Cust123"".
65
+
66
+ 3. **Generate a summary of these tickets**: Finally, we will call the `summarize_objects` API to summarize the tickets. The argument for this call is `(objects, $$PREV[1])`, where `$$PREV[1]` refers to the list of tickets obtained from the `works_list` API.
67
+
68
+ Therefore, the answer is:
69
+
70
+ 1. \[(tool_name: search_object_by_name, arguments: \[(argument_name: query, argument_value: Cust123)\])\],
71
+ 2. \[(tool_name: works_list, arguments: \[(argument_name: ticket.severity, argument_value: high), (argument_name: ticket.source_channel, argument_value: slack), (argument_name: reported_by, argument_value: $$PREV[0])\])\],
72
+ 3. \[(tool_name: summarize_objects, arguments: \[(argument_name: objects, argument_value: $$PREV[1])\])\]."
73
+ "Query: Given a customer meeting transcript T, create action items and add them to my current sprint ","To solve the given task, we need to follow these steps:
74
+
75
+ 1. **Extract Actionable Tasks from Meeting Transcript**: First, we need to extract actionable tasks from the given customer meeting transcript. We will use the `create_actionable_tasks_from_text` API with the argument `text` set to the transcript \(T\).
76
+
77
+
78
+ 2. **Get Current Sprint ID**: To add the tasks to the current sprint, we need to identify the current sprint. We will use the `get_sprint_id` API for this.
79
+
80
+ 3. **Add Extracted Tasks to Sprint**: Finally, we will add the extracted tasks to the identified sprint. We will use the `add_work_items_to_sprint` API with two arguments: `work_ids` set to the result of the `create_actionable_tasks_from_text` API (using $$PREV[0]), and `sprint_id` set to the result of the `get_sprint_id` API (using $$PREV[2]).
81
+
82
+ Therefore, the answer is:
83
+ 1. \[(tool_name: create_actionable_tasks_from_text, argument_name: text, argument_value: T)\],
84
+ 2. \[(tool_name: get_sprint_id, arguments: [ ])\],
85
+ 3. \[(tool_name: add_work_items_to_sprint, arguments: [\[argument_name: work_ids, argument_value: $$PREV[0]\], \[argument_name: sprint_id, argument_value: $$PREV[2]\]])\]."
86
+ Query: What are all the low severity tickets created by InferiorCustomer which needs a response? Generate a summary of them.,"To solve this task, we will need to use multiple APIs in sequence.
87
+
88
+ First, we will call the `search_object_by_name` API to find the ID of ""InferiorCustomer"". We will use the argument `query` with the value ""InferiorCustomer"".
89
+
90
+ Next, we need to retrieve all the low severity tickets created by ""InferiorCustomer"" which need a response. For this, we will use the `works_list` API with three arguments:
91
+ 1. `created_by` with the value of $$PREV[0] to refer to the ID of ""InferiorCustomer"".
92
+ 2. `ticket.severity` with the value ""low"".
93
+ 3. `ticket.needs_response` with the value `true`.
94
+
95
+ Finally, we will summarize these tickets. We use the `summarize_objects` API with the argument `objects` set to the value of $$PREV[1], which refers to the list of tickets retrieved in the previous step.
96
+
97
+ Therefore, the answer is:
98
+ 1. (tool_name: search_object_by_name, arguments = [argument_name: query, argument_value: InferiorCustomer]),
99
+ 2. (tool_name: works_list, arguments = [argument_name: created_by, argument_value: $$PREV[0]], [argument_name: ticket.severity, argument_value: low], [argument_name: ticket.needs_response, argument_value: true]),
100
+ 3. (tool_name: summarize_objects, arguments = [argument_name: objects, argument_value: $$PREV[1]])."
101
+ "Query: Find work items that need a response and are associated with Rev organizations ""Walter LTD"" and ""Hank Products."" List them and summarize their details.","To address the query ""Find work items that need a response and are associated with Rev organizations 'Walter LTD' and 'Hank Products.' List them and summarize their details,"" we need to execute a sequence of API calls with specific arguments. Here is the ordered list of APIs and their corresponding arguments needed to solve this task:
102
+
103
+ 1. **API Call:** `works_list`
104
+ - **Arguments:**
105
+ - `ticket.needs_response`: `true`
106
+ - `ticket.rev_org`: `[""Walter LTD"", ""Hank Products""]`
107
+ - This API call will retrieve a list of work items that require a response and are associated with the specified Rev organizations, ""Walter LTD"" and ""Hank Products.""
108
+
109
+ 2. **API Call:** `summarize_objects`
110
+ - **Arguments:**
111
+ - `objects`: `$$PREV[0]`
112
+ - This API call uses the output from the first API call to summarize the details of the retrieved work items.
113
+
114
+ Therefore, the answer is:
115
+ 1. [(tool_name: works_list, arguments= ([argument_name: ticket.needs_response, argument_value: true], [argument_name: ticket.rev_org, argument_value: [""Walter LTD"", ""Hank Products""]))]
116
+ 2. [(tool_name: summarize_objects, arguments= ([argument_name: objects, argument_value: $$PREV[0]),])]
117
+
118
+ This sequence of API calls will effectively find and summarize the required work items."
119
+ "Query: Get the ID of the current sprint and add the work items with IDs ""WK-123"" and ""WK-456"" to it.
120
+ ","To solve the task of getting the ID of the current sprint and adding the work items with IDs ""WK-123"" and ""WK-456"" to it, we need to sequentially call two APIs.
121
+
122
+ First, we call the `get_sprint_id` API to retrieve the ID of the current sprint. This API does not require any arguments.
123
+
124
+ Next, we use the `add_work_items_to_sprint` API to add the specified work items to the sprint. This requires two arguments:
125
+ 1. `work_ids`: The IDs of the work items to be added to the sprint. In this case, the values are [""WK-123"", ""WK-456""].
126
+ 2. `sprint_id`: The ID of the sprint to which the items should be added. Here, we use the sprint ID obtained from the first API call, referenced as `$$PREV[0]`.
127
+
128
+ Therefore, the solution is:
129
+ 1. [(tool_name: get_sprint_id, arguments: [])]
130
+ 2. [(tool_name: add_work_items_to_sprint, arguments: [(argument_name: work_ids, argument_value: [""WK-123"", ""WK-456""]), (argument_name: sprint_id, argument_value: $$PREV[0])])]"
131
+ "Query: List the first 10 work items owned by user Jonathan in the ""Development"" stage and summarize them.","To solve the task of listing the first 10 work items owned by user Jonathan in the ""Development"" stage and summarizing them, we need to use the following APIs and their arguments:
132
+
133
+ 1. **API Call:** `works_list`
134
+ - **Arguments:**
135
+ - `(argument_name: owned_by, argument_value: [""Jonathan""])` – To filter work items owned by Jonathan.
136
+ - `(argument_name: stage.name, argument_value: [""Development""])` – To filter work items in the Development stage.
137
+ - `(argument_name: limit, argument_value: 10)` – To limit the result to the first 10 work items.
138
+
139
+ 2. **API Call:** `summarize_objects`
140
+ - **Arguments:**
141
+ - `(argument_name: objects, argument_value: $$PREV[0])` – To summarize the list of work items retrieved from the previous API call.
142
+
143
+ Therefore, the answer is:
144
+ - [(tool_name: works_list, arguments= ([argument_name: owned_by, argument_value: [""Jonathan""]], [argument_name: stage.name, argument_value: [""Development""]], [argument_name: limit, argument_value: 10])),
145
+ - (tool_name: summarize_objects, arguments= ([argument_name: objects, argument_value: $$PREV[0]))]"
146
+ Query: List all tickets owned by user Bob Smith in the Customer Support stage where the work item needs a response and provide a summary of these tickets.,"For this task, we need to list and summarize all tickets owned by ""Bob Smith"" in the ""Customer Support"" stage that need a response. We will use the following sequence of APIs and arguments:
147
+
148
+ 1. **API Call:** `works_list`
149
+ - **Arguments:**
150
+ - `(owned_by, [""Bob Smith""])`: To filter tickets owned by Bob Smith.
151
+ - `(stage.name, [""Customer Support""])`: To filter tickets in the Customer Support stage.
152
+ - `(ticket.needs_response, true)`: To filter tickets that need a response.
153
+ - `(type, [""ticket""])`: To specify that we are looking for tickets.
154
+
155
+ 2. **API Call:** `summarize_objects`
156
+ - **Arguments:**
157
+ - `(objects, $$PREV[0])`: To summarize the tickets retrieved from the previous API call.
158
+
159
+ The sequence of API calls and arguments would be:
160
+ 1. `[(tool_name: works_list, arguments: [ (argument_name: owned_by, argument_value: [""Bob Smith""]), (argument_name: stage.name, argument_value: [""Customer Support""]), (argument_name: ticket.needs_response, argument_value: true), (argument_name: type, argument_value: [""ticket""])])],`
161
+ 2. `[(tool_name: summarize_objects, arguments: [(argument_name: objects, argument_value: $$PREV[0])])]`
162
+
163
+ This sequence will first retrieve the relevant tickets and then provide a summary of them."
164
+ "Query: Filter out work items associated with Rev organizations ""Apache"" and ""Nvidia,"" which do not need a response and generate a summary for them. Using this summary, create actions from them and add them to my current sprint.","To solve this task, we need to perform several steps using the given APIs:
165
+
166
+ 1. **Filter work items associated with Rev organizations ""Apache"" and ""Nvidia"" which do not need a response:**
167
+ - We will use the `works_list` API with the following arguments:
168
+ - `(ticket.rev_org, [""Apache"", ""Nvidia""])` to filter by the specified Rev organizations.
169
+ - `(ticket.needs_response, false)` to filter out tickets that do not need a response.
170
+
171
+ 2. **Generate a summary of these filtered work items:**
172
+ - We will then use the `summarize_objects` API with the argument:
173
+ - `(objects, $$PREV[0])` to summarize the objects obtained from the previous API call.
174
+
175
+ 3. **Create actions from the generated summary:**
176
+ - Next, we call the `create_actionable_tasks_from_text` API with the argument:
177
+ - `(text, $$PREV[1])` to create tasks based on the summary text from the previous step.
178
+
179
+ 4. **Add these actions to the current sprint:**
180
+ - To accomplish this, we first need to get the ID of the current sprint using the `get_sprint_id` API with no arguments.
181
+ - Then, we use the `add_work_items_to_sprint` API with the following arguments:
182
+ - `(work_ids, $$PREV[2])` to add the work items (tasks) created in the previous step.
183
+ - `(sprint_id, $$PREV[3])` to specify the current sprint ID obtained from the `get_sprint_id` API.
184
+
185
+ Therefore, the answer is:
186
+ - [(tool_name: works_list, arguments: [(argument_name: ticket.rev_org, argument_value: [""Apache"", ""Nvidia""]), (argument_name: ticket.needs_response, argument_value: false)]),
187
+ - (tool_name: summarize_objects, arguments: [(argument_name: objects, argument_value: $$PREV[0])]),
188
+ - (tool_name: create_actionable_tasks_from_text, arguments: [(argument_name: text, argument_value: $$PREV[1])]),
189
+ - (tool_name: get_sprint_id, arguments: []),
190
+ - (tool_name: add_work_items_to_sprint, arguments: [(argument_name: work_ids, argument_value: $$PREV[2]), (argument_name: sprint_id, argument_value: $$PREV[3])])]"
191
+ "Query: Find and summarize any urgent issues related to my project ""Gladeus""?","To find and summarize any urgent issues related to the project ""Gladeus"", we need to perform a series of API calls:
192
+
193
+ 1. **who_am_i:** First, we need to identify the user making the request. This step is crucial as it ensures that the subsequent actions are tailored to the specific user.
194
+ - Arguments: None
195
+
196
+ 2. **works_list:** After identifying the user, we need to retrieve a list of work items that match the specified criteria, in this case, urgent issues related to the project ""Gladeus"".
197
+ - Arguments:
198
+ - `owned_by`: To filter work items owned by the user identified in the first step. Argument value: `$$PREV[0]` (ID of the current user).
199
+ - `applies_to_part`: To filter work items related to the project ""Gladeus"". Argument value: ""Gladeus"".
200
+ - `issue.priority`: To filter issues by urgency. Argument value: [""p0""] (assuming p0 indicates the highest priority).
201
+
202
+ 3. **summarize_objects:** After retrieving the list of urgent issues related to ""Gladeus"", we need to summarize this list to provide a concise overview.
203
+ - Arguments:
204
+ - `objects`: The list of urgent issues related to ""Gladeus"" obtained from the previous API call. Argument value: `$$PREV[1]`.
205
+
206
+ Therefore, the solution is:
207
+ 1. [(tool_name: who_am_i, arguments: [])],
208
+ 2. [(tool_name: works_list, arguments: [(argument_name: owned_by, argument_value: $$PREV[0]), (argument_name: applies_to_part, argument_value: ""Gladeus""), (argument_name: issue.priority, argument_value: [""p0""])]),
209
+ 3. [(tool_name: summarize_objects, arguments: [(argument_name: objects, argument_value: $$PREV[1])])]."
210
+ Query: Identify and generate a summary of high-severity tickets originating from 'Slack' by customers with the tag 'VIP'.,"To solve this task, we need to identify high-severity tickets originating from 'Slack' and tagged as 'VIP' and then generate a summary of these tickets. Here's how we can achieve this using the given APIs:
211
+
212
+ 1. **Call the `works_list` API** to retrieve a list of work items that match our criteria. We need to use the following arguments:
213
+ - `ticket.severity` with the argument value `high` to filter tickets by high severity.
214
+ - `ticket.source_channel` with the argument value `Slack` to filter tickets originating from Slack.
215
+ - `ticket.rev_org` with a placeholder value `$$PREV[0]` which will be determined in the next step.
216
+
217
+ 2. **Before calling `works_list`, we need to identify the Rev organization ID for customers tagged as 'VIP'**. For this, we use the `search_object_by_name` API with the following arguments:
218
+ - `query` with the argument value `VIP` to search for the Rev organization ID associated with VIP customers.
219
+
220
+ 3. **Finally, call the `summarize_objects` API** to summarize the list of tickets obtained. We use the following argument:
221
+ - `objects` with the argument value `$$PREV[1]` to summarize the tickets obtained from the `works_list` call.
222
+
223
+ Therefore, the answer is:
224
+ 1. [(tool_name: search_object_by_name, argument_name: query, argument_value: VIP),
225
+ 2. (tool_name: works_list, arguments: [(argument_name: ticket.severity, argument_value: high), (argument_name: ticket.source_channel, argument_value: Slack), (argument_name: ticket.rev_org, argument_value: $$PREV[0])]),
226
+ 3. (tool_name: summarize_objects, arguments: [(argument_name: objects, argument_value: $$PREV[1])])]."
227
+ Query: Find all tasks created by me and generate a summary. Add the summarized tasks to the current sprint.,"To solve this task, we need to follow these steps:
228
+
229
+ 1. **Identify the User**: Since the tasks need to be filtered by the ones created by the user, we first need to identify the user. We'll use the `who_am_i` API for this purpose.
230
+
231
+ 2. **List the Tasks Created by the User**: Next, we need to retrieve all tasks that were created by the user. We'll use the `works_list` API with the arguments:
232
+ - `created_by` set to the result of the `who_am_i` API to filter tasks created by the user.
233
+ - `type` set to ""task"" since we are only interested in tasks.
234
+
235
+ 3. **Summarize the Tasks**: Once we have the list of tasks, we need to summarize them. We'll use the `summarize_objects` API with the `objects` argument set to the result of the `works_list` API.
236
+
237
+ 4. **Get the Current Sprint ID**: To add these tasks to the current sprint, we first need to know the ID of the current sprint. We use the `get_sprint_id` API for this.
238
+
239
+ 5. **Add Summarized Tasks to the Sprint**: Finally, we'll use the `add_work_items_to_sprint` API with the arguments:
240
+ - `work_ids` set to the result of the `summarize_objects` API.
241
+ - `sprint_id` set to the result of the `get_sprint_id` API.
242
+
243
+ Therefore, the answer is:
244
+ 1. `[(tool_name: who_am_i, arguments: [])]`
245
+ 2. `[(tool_name: works_list, arguments: [(argument_name: created_by, argument_value: $$PREV[0]), (argument_name: type, argument_value: task)])]`
246
+ 3. `[(tool_name: summarize_objects, arguments: [(argument_name: objects, argument_value: $$PREV[1])])]`
247
+ 4. `[(tool_name: get_sprint_id, arguments: [])]`
248
+ 5. `[(tool_name: add_work_items_to_sprint, arguments: [(argument_name: work_ids, argument_value: $$PREV[2]), (argument_name: sprint_id, argument_value: $$PREV[3])])]`"
249
+ Query: Get the ID of the current sprint and add all tasks assigned to user DEVU-789 to it.,"To solve this task, we need to perform a series of API calls in sequence. The first step is to identify the current sprint, which we can achieve by using the `get_sprint_id` API. This API does not require any arguments.
250
+
251
+ Next, we need to find all tasks assigned to the user ""DEVU-789"". For this, we will use the `works_list` API. The relevant arguments for this API are `owned_by` (to filter tasks assigned to ""DEVU-789"") and `type` (to filter for tasks only).
252
+
253
+ Finally, we need to add these tasks to the current sprint. We will use the `add_work_items_to_sprint` API for this, where `work_ids` will be the list of tasks we found, and `sprint_id` will be the ID of the current sprint we obtained earlier.
254
+
255
+ Therefore, the answer is:
256
+
257
+ 1. Call `get_sprint_id` API (No arguments needed).
258
+ 2. Call `works_list` API with the arguments:
259
+ - `owned_by`: ""DEVU-789""
260
+ - `type`: ""task""
261
+ 3. Call `add_work_items_to_sprint` API with the arguments:
262
+ - `work_ids`: $$PREV[1]
263
+ - `sprint_id`: $$PREV[0]"
Updated_API_list.json ADDED
@@ -0,0 +1 @@
 
 
1
+ [{"name": "works_list", "description": "Returns a list of work items matching the request.", "arguments": [{"argument_name": "applies_to_part", "argument_description": "Filters for work belonging to any of the provided parts", "argument_type": "array of strings"}, {"argument_name": "created_by", "argument_description": "Filters for work created by any of these users", "argument_type": "array of strings"}, {"argument_name": "issue.priority", "argument_description": "Filters for issues with any of the provided priorities. Allowed values: p0, p1, p2, p3", "argument_type": "array of strings"}, {"argument_name": "issue.rev_orgs", "argument_description": "Filters for issues with any of the provided Rev organizations", "argument_type": "array of strings"}, {"argument_name": "limit", "argument_description": "The maximum number of works to return. The default is '50'", "argument_type": "integer (int32)"}, {"argument_name": "owned_by", "argument_description": "Filters for work owned by any of these users", "argument_type": "array of strings"}, {"argument_name": "ticket.needs_response", "argument_description": "Filters for tickets that need a response", "argument_type": "boolean"}, {"argument_name": "ticket.rev_org", "argument_description": "Filters for tickets associated with any of the provided Rev organizations", "argument_type": "array of strings"}, {"argument_name": "ticket.severity", "argument_description": "Filters for tickets with any of the provided severities. Allowed values: blocker, high, low, medium", "argument_type": "array of strings"}, {"argument_name": "ticket.source_channel", "argument_description": "Filters for tickets with any of the provided source channels", "argument_type": "array of strings"}, {"argument_name": "type", "argument_description": "Filters for work of the provided types. Allowed values: issue, ticket, task", "argument_type": "array of strings"}, {"argument_name": "date_of_creation", "argument_description": "Filters for the date of creation of the work item. Allowed format: yyyy-MM-dd HH:mm:ss"}, {"argument_name": "last_modified", "argument_description": "Filters for work items last modified since a specified date. Allowed format: yyyy-MM-dd HH:mm:ss"}, {"argument_name": "target_close_date", "argument_description": "Filter for the timestamp for when the work is expected to be complete. Allowed format: yyyy-MM-dd HH:mm:ss"}]}, {"name": "summarize_objects", "description": "Summarizes a list of objects. The logic of how to summarize a particular object type is an internal implementation detail.", "arguments": [{"argument_name": "objects", "argument_description": "List of objects to summarize", "argument_type": "array of objects"}]}, {"name": "prioritize_objects", "description": "Returns a list of objects sorted by priority. The logic of what constitutes priority for a given object is an internal implementation detail.", "arguments": [{"argument_name": "objects", "argument_description": "A list of objects to be prioritized", "argument_type": "array of objects"}]}, {"name": "add_work_items_to_sprint", "description": "Adds the given work items to the sprint", "arguments": [{"argument_name": "work_ids", "argument_description": "A list of work item IDs to be added to the sprint.", "argument_type": "array of strings"}, {"argument_name": "sprint_id", "argument_description": "The ID of the sprint to which the work items should be added", "argument_type": "string"}]}, {"name": "get_sprint_id", "description": "Returns the ID of the current sprint", "arguments": []}, {"name": "get_similar_work_items", "description": "Returns a list of work items that are similar to the given work item", "arguments": [{"argument_name": "work_id", "argument_description": "The ID of the work item for which you want to find similar items", "argument_type": "string"}]}, {"name": "search_object_by_name", "description": "Given a search string, returns the id of a matching object in the system of record. If multiple matches are found, it returns the one where the confidence is highest.", "arguments": [{"argument_name": "query", "argument_description": "The search string, could be for example customer's name, part name, username.", "argument_type": "string"}]}, {"name": "create_actionable_tasks_from_text", "description": "Given a text, extracts actionable insights, and creates tasks for them, which are kind of a work item.", "arguments": [{"argument_name": "text", "argument_description": "The text from which the actionable insights need to be created.", "argument_type": "string"}]}, {"name": "who_am_i", "description": "Returns the ID of the current user", "arguments": []}, {"name": "is_empty", "description": "Checks if a given list is empty and returns one of two lists based on the result.", "arguments": [{"argument_name": "list_to_check", "argument_description": "The list to be checked for emptiness.", "argument_type": "array"}, {"argument_name": "options", "argument_description": "Two lists of objects. Returns the first one if the list_to_check is empty, otherwise returns the second one.", "argument_type": "array of arrays"}]}, {"name": "count", "description": "Returns the number of work items in the output of an API call.", "arguments": [{"argument_name": "objects", "argument_description": "A list of objects to be counted.", "argument_type": "array of objects"}]}, {"name": "works-create", "description": "Creates work items based on the provided parameters.", "arguments": [{"argument_name": "applies_to_part", "argument_description": "The part that the work applies to. Specifying a part is required when creating tickets and issues. Note: REQUIRED", "argument_type": "array of strings"}, {"argument_name": "created_by", "argument_description": "The users that reported the work", "argument_type": "array of strings"}, {"argument_name": "issue.priority", "argument_description": "The Priority of the work based upon impact and criticality. Allowed values: p0, p1, p2, p3", "argument_type": "string"}, {"argument_name": "developed_with", "argument_description": "The IDs of the parts associated with work item", "argument_type": "array of strings"}, {"argument_name": "owned_by", "argument_description": "The users that own the work. Note: REQUIRED", "argument_type": "array of strings"}, {"argument_name": "stage.name", "argument_description": "Sets an objects initial stage", "argument_type": "string"}, {"argument_name": "sprint", "argument_description": "The sprint that the issue belongs to", "argument_type": "string"}, {"argument_name": "type", "argument_description": "Type of the work item. Allowed values: issue, ticket, task. Note: REQUIRED", "argument_type": "string"}, {"argument_name": "target_close_date", "argument_description": "Timestamp for when the work is expected to be complete. Allowed format: yyyy-MM-dd HH:mm:ss", "argument_type": "date"}, {"argument_name": "title", "argument_description": "Title of the work object; Note: REQUIRED. Allowed values: issue, ticket", "argument_type": "string"}]}, {"name": "works-delete", "description": "Deletes a work item.", "arguments": [{"argument_name": "id", "argument_description": "The work's ID", "argument_type": "array of objects"}]}, {"name": "works-update", "description": "Updates a work item's information", "arguments": [{"argument_name": "id", "argument_description": "id of the work item to be updated. REQUIRED.", "argument_type": "array of strings"}, {"argument_name": "applies_to_part", "argument_description": "Updates the part(s) that the work item applies to.", "argument_type": "array of strings"}, {"argument_name": "created_by", "argument_description": "Sets the users that reported the work to the provided user IDs", "argument_type": "array of strings"}, {"argument_name": "owned_by", "argument_description": "Sets the owner IDs to the provided user IDs. This must not be empty", "argument_type": "array of strings"}, {"argument_name": "stage.name", "argument_description": "The updated name of the stage, otherwise unchanged if not set", "argument_type": "string"}, {"argument_name": "type", "argument_description": "Updates the type of the work item. Allowed values: issue, ticket, task", "argument_type": "string"}, {"argument_name": "target_close_date", "argument_description": "Updates the timestamp for when the work is expected to complete", "argument_type": "date"}, {"argument_name": "title", "argument_description": "Updated title of the work object, or unchanged if not provided", "argument_type": "string"}, {"argument_name": "priority", "argument_description": "Updates the priority of the work item. Allowed values: p0, p1, p2, p3", "argument_type": "string"}]}, {"name": "rev-orgs-create", "description": "Creates a Rev organization based on provided parameters.", "arguments": [{"argument_name": "description", "argument_description": "Description of the Rev organization", "argument_type": "string "}, {"argument_name": "display_name", "argument_description": "Name of the Rev organization", "argument_type": "string"}, {"argument_name": "environment", "argument_description": "The environment of the Org. Defaults to 'production' if not specified.", "argument_type": "string"}]}, {"name": "rev-orgs-delete", "description": "Deletes a Rev organization.", "arguments": [{"argument_name": "id", "argument_description": "Id of the Rev organization to be deleted", "argument_type": "string "}]}, {"name": "rev-orgs-update", "description": "Creates a Rev organization based on provided parameters.", "arguments": [{"argument_name": "description", "argument_description": "Description of the Rev organization", "argument_type": "string "}, {"argument_name": "display_name", "argument_description": "Name of the Rev organization", "argument_type": "string"}, {"argument_name": "environment", "argument_description": "The environment of the Org. Defaults to 'production' if not specified.", "argument_type": "string"}, {"argument_name": "id", "argument_description": "The ID of Rev organization to update.", "argument_type": "string"}]}, {"name": "get_works_id", "description": "Get's the work id of the input objects", "arguments": [{"argument_name": "objects", "argument_description": "List of objects to get ID of", "argument_type": "array of objects"}]}, {"name": "get_current_date", "description": "Get's the current date", "arguments": []}]
all_apis.py ADDED
@@ -0,0 +1,383 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ API_LIST = [
2
+ {
3
+ "name": "works_list",
4
+ "description": "Returns a list of work items matching the request.",
5
+ "arguments": [
6
+ {
7
+ "argument_name": "applies_to_part",
8
+ "argument_description": "Filters for work belonging to any of the provided parts",
9
+ "argument_type": "array of strings"
10
+ },
11
+ {
12
+ "argument_name": "created_by",
13
+ "argument_description": "Filters for work created by any of these users",
14
+ "argument_type": "array of strings"
15
+ },
16
+ {
17
+ "argument_name": "issue.priority",
18
+ "argument_description": "Filters for issues with any of the provided priorities. Allowed values: p0, p1, p2, p3",
19
+ "argument_type": "array of strings"
20
+ },
21
+ {
22
+ "argument_name": "issue.rev_orgs",
23
+ "argument_description": "Filters for issues with any of the provided Rev organizations",
24
+ "argument_type": "array of strings"
25
+ },
26
+ {
27
+ "argument_name": "limit",
28
+ "argument_description": "The maximum number of works to return. The default is '50'",
29
+ "argument_type": "integer (int32)"
30
+ },
31
+ {
32
+ "argument_name": "owned_by",
33
+ "argument_description": "Filters for work owned by any of these users",
34
+ "argument_type": "array of strings"
35
+ },
36
+ {
37
+ "argument_name": "stage.name",
38
+ "argument_description": "Filters for records in the provided stage(s) by name",
39
+ "argument_type": "array of strings"
40
+ },
41
+ {
42
+ "argument_name": "ticket.needs_response",
43
+ "argument_description": "Filters for tickets that need a response",
44
+ "argument_type": "boolean"
45
+ },
46
+ {
47
+ "argument_name": "ticket.rev_org",
48
+ "argument_description": "Filters for tickets associated with any of the provided Rev organizations",
49
+ "argument_type": "array of strings"
50
+ },
51
+ {
52
+ "argument_name": "ticket.severity",
53
+ "argument_description": "Filters for tickets with any of the provided severities. Allowed values: blocker, high, low, medium",
54
+ "argument_type": "array of strings"
55
+ },
56
+ {
57
+ "argument_name": "ticket.source_channel",
58
+ "argument_description": "Filters for tickets with any of the provided source channels",
59
+ "argument_type": "array of strings"
60
+ },
61
+ {
62
+ "argument_name": "type",
63
+ "argument_description": "Filters for work of the provided types. Allowed values: issue, ticket, task",
64
+ "argument_type": "array of strings"
65
+ },
66
+ {
67
+ "argument_name": "date_of_creation",
68
+ "argument_description": "Filters for the date of creation of the work item. Allowed format: yyyy-MM-dd HH:mm:ss"
69
+ },
70
+ {
71
+ "argument_name": "last_modified",
72
+ "argument_description": "Filters for work items last modified since a specified date. Allowed format: yyyy-MM-dd HH:mm:ss"
73
+ },
74
+ {
75
+ "argument_name": "target_close_date",
76
+ "argument_description": "Filter for the timestamp for when the work is expected to be complete. Allowed format: yyyy-MM-dd HH:mm:ss"
77
+ }
78
+ ]
79
+ },
80
+ {
81
+ "name": "summarize_objects",
82
+ "description": "Summarizes a list of objects. The logic of how to summarize a particular object type is an internal implementation detail.",
83
+ "arguments": [
84
+ {
85
+ "argument_name": "objects",
86
+ "argument_description": "List of objects to summarize",
87
+ "argument_type": "array of objects"
88
+ }
89
+ ]
90
+ },
91
+
92
+ {
93
+ "name": "prioritize_objects",
94
+ "description": "Returns a list of objects sorted by priority. The logic of what constitutes priority for a given object is an internal implementation detail.",
95
+ "arguments": [
96
+ {
97
+ "argument_name": "objects",
98
+ "argument_description": "A list of objects to be prioritized",
99
+ "argument_type": "array of objects"
100
+ }
101
+ ]
102
+ },
103
+ {
104
+ "name": "add_work_items_to_sprint",
105
+ "description": "Adds the given work items to the sprint",
106
+ "arguments": [
107
+ {
108
+ "argument_name": "work_ids",
109
+ "argument_description": "A list of work item IDs to be added to the sprint.",
110
+ "argument_type": "array of strings"
111
+ },
112
+ {
113
+ "argument_name": "sprint_id",
114
+ "argument_description": "The ID of the sprint to which the work items should be added",
115
+ "argument_type": "string"
116
+ }
117
+ ]
118
+ },
119
+ {
120
+ "name": "get_sprint_id",
121
+ "description": "Returns the ID of the current sprint",
122
+ "arguments": []
123
+ },
124
+ {
125
+ "name": "get_similar_work_items",
126
+ "description": "Returns a list of work items that are similar to the given work item",
127
+ "arguments": [
128
+ {
129
+ "argument_name": "work_id",
130
+ "argument_description": "The ID of the work item for which you want to find similar items",
131
+ "argument_type": "string"
132
+ }
133
+ ]
134
+ },
135
+ {
136
+ "name": "search_object_by_name",
137
+ "description": "Given a search string, returns the id of a matching object in the system of record. If multiple matches are found, it returns the one where the confidence is highest.",
138
+ "arguments": [
139
+ {
140
+ "argument_name": "query",
141
+ "argument_description": "The search string, could be for example customer's name, part name, username.",
142
+ "argument_type": "string"
143
+ }
144
+ ]
145
+ },
146
+ {
147
+ "name": "create_actionable_tasks_from_text",
148
+ "description": "Given a text, extracts actionable insights, and creates tasks for them, which are kind of a work item.",
149
+ "arguments": [
150
+ {
151
+ "argument_name": "text",
152
+ "argument_description": "The text from which the actionable insights need to be created.",
153
+ "argument_type": "string"
154
+ }
155
+ ]
156
+ },
157
+ {
158
+ "name": "who_am_i",
159
+ "description": "Returns the ID of the current user",
160
+ "arguments": []
161
+ },
162
+ {
163
+ "name": "is_empty",
164
+ "description": "Checks if a given list is empty and returns one of two lists based on the result.",
165
+ "arguments": [
166
+ {
167
+ "argument_name": "list_to_check",
168
+ "argument_description": "The list to be checked for emptiness.",
169
+ "argument_type": "array"
170
+ },
171
+ {
172
+ "argument_name": "options",
173
+ "argument_description": "Two lists of objects. Returns the first one if the list_to_check is empty, otherwise returns the second one.",
174
+ "argument_type": "array of arrays"
175
+ }
176
+ ]
177
+ },
178
+ {
179
+ "name": "count",
180
+ "description": "Returns the number of work items in the output of an API call.",
181
+ "arguments": [
182
+ {
183
+ "argument_name": "objects",
184
+ "argument_description": "A list of objects to be counted.",
185
+ "argument_type": "array of objects"
186
+ }
187
+ ]
188
+ },
189
+ {
190
+ "name": "works-create",
191
+ "description": "Creates work items based on the provided parameters.",
192
+ "arguments": [
193
+ {
194
+ "argument_name": "applies_to_part",
195
+ "argument_description": "The part that the work applies to. Specifying a part is required when creating tickets and issues. Note: REQUIRED",
196
+ "argument_type": "array of strings"
197
+ },
198
+ {
199
+ "argument_name": "created_by",
200
+ "argument_description": "The users that reported the work",
201
+ "argument_type": "array of strings"
202
+ },
203
+ {
204
+ "argument_name": "issue.priority",
205
+ "argument_description": "The Priority of the work based upon impact and criticality. Allowed values: p0, p1, p2, p3",
206
+ "argument_type": "string"
207
+ },
208
+ {
209
+ "argument_name": "developed_with",
210
+ "argument_description": "The IDs of the parts associated with work item",
211
+ "argument_type": "array of strings"
212
+ },
213
+ {
214
+ "argument_name": "owned_by",
215
+ "argument_description": "The users that own the work. Note: REQUIRED",
216
+ "argument_type": "array of strings"
217
+ },
218
+ {
219
+ "argument_name": "stage.name",
220
+ "argument_description": "Sets an objects initial stage",
221
+ "argument_type": "string"
222
+ },
223
+ {
224
+ "argument_name": "sprint",
225
+ "argument_description": "The sprint that the issue belongs to",
226
+ "argument_type": "string"
227
+ },
228
+ {
229
+ "argument_name": "type",
230
+ "argument_description": "Type of the work item. Allowed values: issue, ticket, task. Note: REQUIRED",
231
+ "argument_type": "string"
232
+ },
233
+ {
234
+ "argument_name": "target_close_date",
235
+ "argument_description": "Timestamp for when the work is expected to be complete. Allowed format: yyyy-MM-dd HH:mm:ss",
236
+ "argument_type": "date"
237
+ },
238
+ {
239
+ "argument_name": "title",
240
+ "argument_description": "Title of the work object; Note: REQUIRED. Allowed values: issue, ticket",
241
+ "argument_type": "string"
242
+ }
243
+ ]
244
+ },
245
+ {
246
+ "name": "works-delete",
247
+ "description": "Deletes a work item.",
248
+ "arguments": [
249
+ {
250
+ "argument_name": "id",
251
+ "argument_description": "The work's ID",
252
+ "argument_type": "array of objects"
253
+ }
254
+ ]
255
+ },
256
+ {
257
+ "name": "works-update",
258
+ "description": "Updates a work item's information",
259
+ "arguments": [
260
+ {
261
+ "argument_name": "id",
262
+ "argument_description": "id of the work item to be updated. REQUIRED.",
263
+ "argument_type": "array of strings"
264
+ },
265
+ {
266
+ "argument_name": "applies_to_part",
267
+ "argument_description": "Updates the part(s) that the work item applies to.",
268
+ "argument_type": "array of strings"
269
+ },
270
+ {
271
+ "argument_name": "created_by",
272
+ "argument_description": "Sets the users that reported the work to the provided user IDs",
273
+ "argument_type": "array of strings"
274
+ },
275
+ {
276
+ "argument_name": "owned_by",
277
+ "argument_description": "Sets the owner IDs to the provided user IDs. This must not be empty",
278
+ "argument_type": "array of strings"
279
+ },
280
+ {
281
+ "argument_name": "stage.name",
282
+ "argument_description": "The updated name of the stage, otherwise unchanged if not set",
283
+ "argument_type": "string"
284
+ },
285
+ {
286
+ "argument_name": "type",
287
+ "argument_description": "Updates the type of the work item. Allowed values: issue, ticket, task",
288
+ "argument_type": "string"
289
+ },
290
+ {
291
+ "argument_name": "target_close_date",
292
+ "argument_description": "Updates the timestamp for when the work is expected to complete",
293
+ "argument_type": "date"
294
+ },
295
+ {
296
+ "argument_name": "title",
297
+ "argument_description": "Updated title of the work object, or unchanged if not provided",
298
+ "argument_type": "string"
299
+ },
300
+ {
301
+ "argument_name": "priority",
302
+ "argument_description": "Updates the priority of the work item. Allowed values: p0, p1, p2, p3",
303
+ "argument_type": "string"
304
+ }
305
+ ]
306
+ },
307
+ {
308
+ "name": "rev-orgs-create",
309
+ "description": "Creates a Rev organization based on provided parameters.",
310
+ "arguments": [
311
+ {
312
+ "argument_name": "description",
313
+ "argument_description": "Description of the Rev organization",
314
+ "argument_type": "string "
315
+ },
316
+ {
317
+ "argument_name": "display_name",
318
+ "argument_description": "Name of the Rev organization",
319
+ "argument_type": "string"
320
+ },
321
+ {
322
+ "argument_name": "environment",
323
+ "argument_description": "The environment of the Org. Defaults to 'production' if not specified.",
324
+ "argument_type": "string"
325
+ }
326
+ ]
327
+ },
328
+ {
329
+ "name": "rev-orgs-delete",
330
+ "description": "Deletes a Rev organization.",
331
+ "arguments": [
332
+ {
333
+ "argument_name": "id",
334
+ "argument_description": "Id of the Rev organization to be deleted",
335
+ "argument_type": "string "
336
+ }
337
+ ]
338
+ },
339
+
340
+ {
341
+ "name": "rev-orgs-update",
342
+ "description": "Creates a Rev organization based on provided parameters.",
343
+ "arguments": [
344
+ {
345
+ "argument_name": "description",
346
+ "argument_description": "Description of the Rev organization",
347
+ "argument_type": "string "
348
+ },
349
+ {
350
+ "argument_name": "display_name",
351
+ "argument_description": "Name of the Rev organization",
352
+ "argument_type": "string"
353
+ },
354
+ {
355
+ "argument_name": "environment",
356
+ "argument_description": "The environment of the Org. Defaults to 'production' if not specified.",
357
+ "argument_type": "string"
358
+ },
359
+ {
360
+ "argument_name": "id",
361
+ "argument_description": "The ID of Rev organization to update.",
362
+ "argument_type": "string"
363
+ }
364
+ ]
365
+ },
366
+ {
367
+ "name": "get_works_id",
368
+ "description": "Get's the work id of the input objects",
369
+ "arguments": [
370
+ {
371
+ "argument_name": "objects",
372
+ "argument_description": "List of objects to get ID of",
373
+ "argument_type": "array of objects"
374
+ }
375
+ ]
376
+ },
377
+ {
378
+ "name": "get_current_date",
379
+ "description": "Get's the current date",
380
+ "arguments": []
381
+ }
382
+
383
+ ]
api_json_to_doc.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from all_apis import API_LIST
2
+
3
+ # Function to convert JSON to documentation format
4
+ def convert_json_to_doc(API_LIST):
5
+ documentation = ""
6
+ for idx, api in enumerate(API_LIST):
7
+ documentation += f"#### {idx+1}. {api['name']}\n"
8
+ documentation += f"- *API Description:* {api['description']}\n"
9
+ if api["arguments"]:
10
+ documentation += "- **Arguments:**\n"
11
+ for arg in api["arguments"]:
12
+ try:
13
+ documentation += f" - {arg['argument_name']}:\n"
14
+ except:
15
+ pass
16
+ try:
17
+ documentation += f" - Argument Description: {arg['argument_description']}\n"
18
+ except:
19
+ pass
20
+ try:
21
+ documentation += f" - Argument Type: {arg['argument_type']}\n"
22
+ except:
23
+ pass
24
+ return documentation
app.py ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from imports import *
2
+ from pipelines import *
3
+ from hal_check import *
4
+ from prompts import *
5
+ from prompt_templates import *
6
+ from retrieval import *
7
+ from all_apis import *
8
+ from prompts import *
9
+ from update_api_toolset import *
10
+ from mem_check import *
11
+ warnings.filterwarnings('ignore')
12
+
13
+ # retrieval examples
14
+ retrieval_loader = CSVLoader(file_path=r'Seed_Dataset.csv', source_column = 'QUERY')
15
+ retrieval_data = retrieval_loader.load()
16
+ retrieval_embeddings = HuggingFaceEmbeddings()
17
+
18
+ if "available_tools" not in st.session_state:
19
+ st.session_state.available_tools = available_tools.copy()
20
+
21
+ if "available_arguments" not in st.session_state:
22
+ st.session_state.available_arguments = available_arguments.copy()
23
+
24
+ if "arg_allowed_values_dict" not in st.session_state:
25
+ st.session_state.arg_allowed_values_dict = arg_allowed_values_dict.copy()
26
+
27
+ if "args_in_list_dict" not in st.session_state:
28
+ st.session_state.args_in_list_dict = args_in_list_dict.copy()
29
+
30
+ if "api_list_updated" not in st.session_state:
31
+ st.session_state.api_list_updated = API_LIST.copy()
32
+
33
+ if "retrieval_vector_db" not in st.session_state:
34
+ st.session_state.retrieval_vector_db = FAISS.from_documents(
35
+ documents=retrieval_data,
36
+ embedding=retrieval_embeddings,
37
+ )
38
+
39
+ # Initialize session state for messages if not already present
40
+ if "messages" not in st.session_state:
41
+ st.session_state.messages = []
42
+
43
+ if "PAST_QUERY" not in st.session_state:
44
+ st.session_state.PAST_QUERY = "NO PAST QUERIES"
45
+ st.session_state.PAST_RESPONSE = "NO PAST RESPONSES"
46
+ st.session_state.PREV_QUERY = ""
47
+ st.session_state.PREV_RESPONSE = ""
48
+
49
+ # Function to clear the session state variable
50
+ def clear_api_list_updated():
51
+ st.session_state.api_list_updated = API_LIST.copy()
52
+ st.session_state.args_in_list_dict = args_in_list_dict.copy()
53
+ st.session_state.arg_allowed_values_dict = arg_allowed_values_dict.copy()
54
+ st.session_state.available_arguments = available_arguments.copy()
55
+ st.session_state.available_tools = available_tools.copy()
56
+ st.session_state.retrieval_vector_db = FAISS.from_documents(
57
+ documents=retrieval_data,
58
+ embedding=retrieval_embeddings,
59
+ )
60
+
61
+ # file_path = r'Updated_API_list.json'
62
+
63
+ # Page navigation
64
+ st.sidebar.title("Navigation")
65
+ page = st.sidebar.radio("Go to", ["Chatbot", "Tool Management", "API_LIST"])
66
+
67
+ if page == "Chatbot":
68
+ # Chatbot UI Code
69
+ st.title("DevRev AI Agent")
70
+
71
+ # Display chat messages from history
72
+ for message in st.session_state.messages:
73
+ with st.chat_message(message["role"]):
74
+ st.markdown(message["content"])
75
+
76
+ # Accept user input
77
+ if prompt := st.chat_input("What is up?"):
78
+ print("okay")
79
+ st.session_state.messages.append({"role": "user", "content": prompt})
80
+ with st.chat_message("user"):
81
+ st.markdown(prompt)
82
+ print(f"User query: {prompt}")
83
+ query = prompt
84
+ with st.chat_message("assistant"):
85
+ message_placeholder = st.empty()
86
+ json_answer = pipeline(query, st.session_state.api_list_updated, st.session_state.available_tools, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict, st.session_state.retrieval_vector_db) # allowed args dict ka placeholder modify karna bacha
87
+ full_response = json_answer
88
+ try:
89
+ message_placeholder.json(full_response)
90
+ except:
91
+ message_placeholder.markdown(full_response)
92
+ st.session_state.messages.append({"role": "assistant", "content": full_response})
93
+
94
+ elif page == "Tool Management":
95
+ print("TOOLS")
96
+ # Tool Management Code
97
+ st.title("API Tool Management")
98
+
99
+ # Load or initialize the API list in session state
100
+ if "api_list_updated" not in st.session_state:
101
+ st.session_state.api_list_updated = API_LIST
102
+
103
+ # Button to trigger the clearing action
104
+ if st.button("Reset API list"):
105
+ clear_api_list_updated()
106
+
107
+ # Add a new tool
108
+ st.header("Add a New Tool")
109
+ with st.form("new_tool_form"):
110
+ new_tool_name = st.text_input("Tool Name")
111
+ new_tool_desc = st.text_area("Tool Description")
112
+ submitted = st.form_submit_button("Add Tool")
113
+ if submitted:
114
+ st.session_state.api_list_updated, st.session_state.available_tools, st.session_state.available_arguments = add_tool(st.session_state.api_list_updated, new_tool_name, new_tool_desc, st.session_state.available_tools, st.session_state.available_arguments, st.session_state.retrieval_vector_db)
115
+ st.success("Tool Added Successfully!")
116
+
117
+ if st.session_state.api_list_updated:
118
+ selected_tool_name = st.selectbox("Select a tool", options=[tool["name"] for tool in st.session_state.api_list_updated])
119
+ selected_tool = next((tool for tool in st.session_state.api_list_updated if tool['name'] == selected_tool_name), None)
120
+
121
+ # Update or Delete Tools
122
+ st.header("Update or Delete Tools")
123
+ if selected_tool:
124
+ with st.form("update_delete_tool_form"):
125
+ st.write(f"Selected Tool: {selected_tool_name}")
126
+ new_name = st.text_input("New Name", value=selected_tool['name'])
127
+ new_description = st.text_area("New Description", value=selected_tool['description'])
128
+ update_button = st.form_submit_button("Update Tool")
129
+ delete_button = st.form_submit_button("Delete Tool")
130
+
131
+ if update_button:
132
+ st.session_state.api_list_updated, st.session_state.available_tools, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict = update_tool(st.session_state.api_list_updated, selected_tool_name, new_name, new_description, st.session_state.available_tools, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict, st.session_state.retrieval_vector_db)
133
+ st.success("Tool Updated Successfully!")
134
+
135
+ if delete_button:
136
+ st.session_state.api_list_updated, st.session_state.available_tools, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict, st.session_state.retrieval_vector_db = delete_tool(st.session_state.api_list_updated, selected_tool_name, st.session_state.available_tools, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict, st.session_state.retrieval_vector_db)
137
+ st.success("Tool Deleted Successfully!")
138
+
139
+ # Add a New Argument to a Tool
140
+ st.header("Add a New Argument to a Tool")
141
+ # if st.session_state.api_list_updated: # Check if there are tools available
142
+ # selected_tool_name = st.selectbox("Select a tool to add an argument", options=[tool["name"] for tool in st.session_state.api_list_updated])
143
+ if selected_tool:
144
+ with st.form("new_argument_form"):
145
+ new_arg_name = st.text_input("Argument Name")
146
+ new_arg_desc = st.text_area("Argument Description")
147
+ new_arg_allowed_values = st.text_area("Argument Allowed Values")
148
+ new_arg_type = st.text_input("Argument Type")
149
+ submitted_arg = st.form_submit_button("Add Argument")
150
+ if submitted_arg:
151
+ st.session_state.api_list_updated, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict= add_argument(st.session_state.api_list_updated, selected_tool_name, new_arg_name, new_arg_desc, new_arg_type, new_arg_allowed_values, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict, st.session_state.retrieval_vector_db)
152
+ arg_allowed_values_dict[f"{selected_tool_name}/{new_arg_name}"] = new_arg_allowed_values
153
+ st.success("Argument Added Successfully!")
154
+ else:
155
+ st.write("No tools available. Add a tool first.")
156
+
157
+
158
+ # Update or Delete Arguments
159
+ st.header("Update or Delete Arguments")
160
+ if selected_tool:
161
+ st.write(f"Selected Tool: {selected_tool_name}")
162
+ selected_arg_name = st.selectbox("Select an argument", options=[arg["argument_name"] for arg in selected_tool["arguments"]])
163
+ selected_arg = next((arg for arg in selected_tool['arguments'] if arg['argument_name'] == selected_arg_name), None)
164
+
165
+ if selected_arg:
166
+ with st.form("update_delete_arg_form"):
167
+ new_arg_name = st.text_input("New Argument Name", value=selected_arg['argument_name'])
168
+ new_arg_desc = st.text_area("New Argument Description", value=selected_arg['argument_description'])
169
+ if f"{selected_tool_name}/{selected_arg_name}" in arg_allowed_values_dict:
170
+ new_arg_allowed_values = st.text_area("New Argument Allowed Values", value=arg_allowed_values_dict[f"{selected_tool_name}/{selected_arg_name}"])
171
+ else:
172
+ new_arg_allowed_values = st.text_area("New Argument Allowed Values")
173
+ new_arg_type = st.text_input("New Argument Type", value=selected_arg['argument_type'])
174
+ update_arg_button = st.form_submit_button("Update Argument")
175
+ delete_arg_button = st.form_submit_button("Delete Argument")
176
+
177
+ if update_arg_button:
178
+ st.session_state.api_list_updated, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict = update_argument(st.session_state.api_list_updated, selected_tool_name, selected_arg_name, new_arg_name, new_arg_desc, new_arg_type, new_arg_allowed_values, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict, st.session_state.retrieval_vector_db)
179
+ arg_allowed_values_dict[f"{selected_tool_name}/{new_arg_name}"] = new_arg_allowed_values
180
+ st.success("Argument Updated Successfully!")
181
+
182
+ if delete_arg_button:
183
+ st.session_state.api_list_updated, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict = delete_argument(st.session_state.api_list_updated, selected_tool_name, selected_arg_name, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict, st.session_state.retrieval_vector_db)
184
+ st.success("Argument Deleted Successfully!")
185
+
186
+ # Delete Multiple Arguments
187
+ if selected_tool:
188
+ st.header("Delete Multiple Arguments from Tool")
189
+ all_arg_names = [arg["argument_name"] for arg in selected_tool["arguments"]]
190
+ selected_args_to_delete = st.multiselect("Select arguments to delete from the tool", options=all_arg_names)
191
+ if st.button("Delete Selected Arguments"):
192
+ st.session_state.api_list_updated, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict = delete_multiple_arguments(st.session_state.api_list_updated, selected_tool_name, selected_args_to_delete, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict, st.session_state.retrieval_vector_db)
193
+ st.success("Selected Arguments Deleted Successfully!")
194
+
195
+ # Display the current API list
196
+ st.header("Current API List")
197
+ st.text(json.dumps(st.session_state.api_list_updated, indent=2))
198
+
199
+ with open(file_path, 'w') as file:
200
+ json.dump(st.session_state.api_list_updated, file)
201
+ elif page == "API_LIST":
202
+ st.session_state.api_list_updated, st.session_state.available_tools, st.session_state.available_arguments, st.session_state.arg_allowed_values_dict, st.session_state.args_in_list_dict
203
+ st.write(len(st.session_state.retrieval_vector_db.docstore._dict))
hal_check.py ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ast
2
+ import re
3
+ from collections import OrderedDict
4
+
5
+ available_tools = [
6
+ "works_list",
7
+ "summarize_objects",
8
+ "prioritize_objects",
9
+ "add_work_items_to_sprint",
10
+ "get_sprint_id",
11
+ "get_similar_work_items",
12
+ "search_object_by_name",
13
+ "create_actionable_tasks_from_text",
14
+ "who_am_i",
15
+ "is_empty",
16
+ "count",
17
+ "works-create",
18
+ "works-delete",
19
+ "works-update",
20
+ "rev-orgs-create",
21
+ "rev-orgs-delete",
22
+ "rev-orgs-update",
23
+ "get_works_id",
24
+ "get_current_date"
25
+ ]
26
+ available_arguments = [
27
+ "works_list/applies_to_part",
28
+ "works_list/created_by",
29
+ "works_list/issue.priority",
30
+ "works_list/issue.rev_orgs",
31
+ "works_list/limit",
32
+ "works_list/owned_by",
33
+ "works_list/stage.name",
34
+ "works_list/ticket.needs_response",
35
+ "works_list/ticket.rev_org",
36
+ "works_list/ticket.severity",
37
+ "works_list/ticket.source_channel",
38
+ "works_list/type",
39
+ "works_list/date_of_creation",
40
+ "works_list/last_modified",
41
+ "works_list/target_close_date",
42
+ "works_list/sprint",
43
+ "summarize_objects/objects",
44
+ "prioritize_objects/objects",
45
+ "add_work_items_to_sprint/work_ids",
46
+ "add_work_items_to_sprint/sprint_id",
47
+ "get_sprint_id/",
48
+ "get_similar_work_items/work_id",
49
+ "search_object_by_name/query",
50
+ "create_actionable_tasks_from_text/text",
51
+ "who_am_i/",
52
+ "is_empty/list_to_check",
53
+ "count/objects",
54
+ "works-create/applies_to_part",
55
+ "works-create/created_by",
56
+ "works-create/issue.priority",
57
+ "works-create/developed_with",
58
+ "works-create/owned_by",
59
+ "works-create/stage.name",
60
+ "works-create/sprint",
61
+ "works-create/type",
62
+ "works-create/target_close_date",
63
+ "works-create/title",
64
+ "works-delete/id",
65
+ "works-update/id",
66
+ "works-update/applies_to_part",
67
+ "works-update/created_by",
68
+ "works-update/owned_by",
69
+ "works-update/stage.name",
70
+ "works-update/type",
71
+ "works-update/target_close_date",
72
+ "works-update/title",
73
+ "works-update/priority",
74
+ "rev-orgs-create/description",
75
+ "rev-orgs-create/display_name",
76
+ "rev-orgs-create/environment",
77
+ "rev-orgs-delete/id",
78
+ "rev-orgs-update/description",
79
+ "rev-orgs-update/display_name",
80
+ "rev-orgs-update/environment",
81
+ "rev-orgs-update/id",
82
+ "get_works_id/objects",
83
+ "get_current_date/"
84
+ ]
85
+
86
+ arg_allowed_values_dict = {'works-update/priority': ['p0', 'p1', 'p2', 'p3'],
87
+ 'works-update/type': ['issue', 'task', 'ticket'],
88
+ 'works_list/issue.priority': ['p0', 'p1', 'p2', 'p3'],
89
+ 'works_list/ticket.needs_response': ['true', 'false'],
90
+ 'works_list/ticket.severity': ['blocker', 'low', 'medium', 'high'],
91
+ 'works_list/type': ['issue', 'task', 'ticket'],
92
+ 'works-create/issue.priority': ['p0', 'p1', 'p2', 'p3'],
93
+ 'works-create/type': ['issue', 'task', 'ticket'],
94
+ 'works-create/title': ['issue', 'ticket']}
95
+
96
+ args_in_list_dict = {
97
+ 'works_list/applies_to_part': 1,
98
+ 'works_list/created_by': 1,
99
+ 'works_list/issue.priority': 1,
100
+ 'works_list/issue.rev_orgs': 1,
101
+ 'works_list/limit': 0,
102
+ 'works_list/owned_by': 1,
103
+ 'works_list/stage.name': 1,
104
+ 'works_list/ticket.needs_response': 0,
105
+ 'works_list/ticket.rev_org': 1,
106
+ 'works_list/ticket.severity': 1,
107
+ 'works_list/ticket.source_channel': 1,
108
+ 'works_list/type': 1,
109
+ 'works_list/date_of_creation': 0,
110
+ 'works_list/last_modified': 0,
111
+ 'works_list/target_close_date': 0,
112
+ 'works_list/sprint': 1,
113
+ 'summarize_objects/objects': 1,
114
+ 'prioritize_objects/objects': 1,
115
+ 'add_work_items_to_sprint/work_ids': 1,
116
+ 'add_work_items_to_sprint/sprint_id': 0,
117
+ 'get_similar_work_items/work_id': 0,
118
+ 'search_object_by_name/query': 0,
119
+ 'create_actionable_tasks_from_text/text': 0,
120
+ 'is_empty/list_to_check': 0,
121
+ 'count/objects': 1,
122
+ 'works-create/applies_to_part': 1,
123
+ 'works-create/created_by': 1,
124
+ 'works-create/issue.priority': 1,
125
+ 'works-create/developed_with': 1,
126
+ 'works-create/owned_by': 1,
127
+ 'works-create/stage.name': 1,
128
+ 'works-create/sprint': 1,
129
+ 'works-create/type': 1,
130
+ 'works-create/target_close_date': 0,
131
+ 'works-create/title': 0,
132
+ 'works-delete/id': 1,
133
+ 'works-update/id': 1,
134
+ 'works-update/applies_to_part': 1,
135
+ 'works-update/created_by': 1,
136
+ 'works-update/owned_by': 1,
137
+ 'works-update/stage.name': 1,
138
+ 'works-update/type': 1,
139
+ 'works-update/target_close_date': 0,
140
+ 'works-update/title': 0,
141
+ 'works-update/priority': 1,
142
+ 'rev-orgs-create/description': 0,
143
+ 'rev-orgs-create/display_name': 0,
144
+ 'rev-orgs-create/environment': 0,
145
+ 'rev-orgs-delete/id': 0,
146
+ 'rev-orgs-update/description': 0,
147
+ 'rev-orgs-update/display_name': 0,
148
+ 'rev-orgs-update/environment': 0,
149
+ 'rev-orgs-update/id': 0,
150
+ 'get_works_id/objects': 1,
151
+ 'get_current_date/': 0
152
+ }
153
+
154
+
155
+ def find_hallucinations(json_response, arg_allowed_values_dict, available_tools, available_arguments, args_in_list_dict):
156
+ # check errors in names of tools and arguments
157
+ for i, item in enumerate(json_response):
158
+ print(item)
159
+ if 'tool_name' not in item:
160
+ if type(item) is dict:
161
+ first_key = list(item.keys())[0]
162
+ first_value = item.pop(first_key)
163
+ # Create a new dictionary with 'tool_name' and the rest of the key-value pairs
164
+ new_item = {'tool_name': first_value, **item}
165
+ json_response[i] = new_item
166
+ else:
167
+ item = 'tool_name'
168
+
169
+ tool_names = [item['tool_name'] for item in json_response]
170
+ print(f"tool_names:{tool_names}")
171
+ print(f"available_tools:{available_tools}")
172
+ print(f"available_arguments:{available_arguments}")
173
+ valid_tools = [tool_name for tool_name in tool_names if tool_name in available_tools]
174
+ print(f"valid_tools:{valid_tools}")
175
+ hallucinated_tools = [tool_name for tool_name in tool_names if tool_name not in available_tools]
176
+ print(f"hallucinated_tools:{hallucinated_tools}")
177
+ argument_names = []
178
+
179
+ for item in json_response:
180
+ for key in item:
181
+ if item[key] in valid_tools:
182
+ # try:
183
+ arguments = item.get("arguments", [])
184
+ for argument in arguments:
185
+ argument_name = argument.get("argument_name")
186
+ if argument_name:
187
+ argument_names.append(item["tool_name"]+"/"+argument_name)
188
+ # except AttributeError:
189
+ # pass
190
+ # valid_args = [arg_name for arg_name in argument_names if arg_name in merged_arguments]
191
+ hallucinated_args = [arg_name for arg_name in argument_names if arg_name not in available_arguments]
192
+ # check the validity of argument values using allowed_arg_values_dict
193
+ json_args_dict = {}
194
+ for item in json_response:
195
+ for key in item:
196
+ if item[key] in available_tools:
197
+ # try:
198
+ arguments = item.get("arguments", [])
199
+ for argument in arguments:
200
+ argument_name = argument.get("argument_name")
201
+ if argument_name:
202
+ json_args_dict[item["tool_name"]+"/"+argument_name] = argument["argument_value"]
203
+ concat_arg = item["tool_name"] + "/" + argument_name
204
+ argument_names.append(concat_arg)
205
+ # try:
206
+ if args_in_list_dict[concat_arg] == 1: ## fixes the arguments that are supposed to be in a list format but are not
207
+ arg_val = argument.get("argument_value")
208
+ if type(arg_val) is not list:
209
+ l = []
210
+ l.append(arg_val)
211
+ argument["argument_value"] = l
212
+ # except KeyError:
213
+ # pass
214
+ # except AttributeError:
215
+ # pass
216
+
217
+ hallucinated_args_values_prev = []
218
+ for idx, item in enumerate(json_response):
219
+ for key in item:
220
+ if item[key] in available_tools:
221
+ # try:
222
+ arguments = item.get("arguments", [])
223
+ for argument in arguments:
224
+ argument_name = argument.get("argument_name")
225
+
226
+ if argument_name:
227
+ json_args_dict[item["tool_name"]+"/"+argument_name] = argument["argument_value"]
228
+ # print("argument value ", argument['argument_value'])
229
+ # try:
230
+ print("argument value", argument['argument_value'])
231
+ arg_list = ast.literal_eval(argument['argument_value'])
232
+ for arg in arg_list:
233
+ # print("arument 2, ", arg)
234
+ if ("$$PREV" in arg and int(arg.split("[")[1].split("]")[0])):
235
+ hallucinated_args_values_prev.append((item["tool_name"] + "/" + argument_name, arg))
236
+ # except:
237
+ # pass
238
+ # except AttributeError:
239
+ # pass
240
+
241
+ hallucinated_args_values = []
242
+ for arg_name, arg_value in json_args_dict.items():
243
+ if arg_name in arg_allowed_values_dict:
244
+ if type(arg_value) is not list:
245
+ if arg_value not in arg_allowed_values_dict[arg_name]:
246
+ hallucinated_args_values.append((arg_name, arg_value))
247
+ else:
248
+ for i in arg_value:
249
+ if i not in arg_allowed_values_dict[arg_name]:
250
+ hallucinated_args_values.append((arg_name, i))
251
+ return hallucinated_args, hallucinated_tools, hallucinated_args_values, hallucinated_args_values_prev
252
+
253
+ def correction(hallucinated_args, hallucinated_args_values, hallucinated_tools, hallucinated_args_values_prev, json_response):
254
+ Correction_prompt = ''
255
+ Correction_prompt += f'These are the following errors in your previous json response \n {json_response} \n'
256
+ for i in hallucinated_args:
257
+ Correction_prompt += f"The argument {i} is used but is not present in the provided API list. \n"
258
+ for i in hallucinated_tools:
259
+ Correction_prompt += f"The tool {i} is used but is not present in the provided API list. \n"
260
+ for i, j in hallucinated_args_values:
261
+ Correction_prompt += f"Argument_value '{j}' for argument '{i}' is not valid according to the specified API list. \n"
262
+ for i, j in hallucinated_args_values_prev:
263
+ Correction_prompt += f"Argument_value '{j}' for argument '{i}' is not valid since it refers to an item in the API list that does not come before it.\n"
264
+ Correction_prompt += "You have to give the corrected solution to the product manager's query by modifying the provided JSON. You have to remove hallucinations and only output the corrected JSON. \n"
265
+ return Correction_prompt
266
+
267
+ def correction_if_wrong_schema(exception, json_response):
268
+ Correction_prompt = 'The json you extracted in your response does not follow the appropriate json schema' + '\n'
269
+ Correction_prompt += f'Upon extracting your json response : \n {json_response} \n'
270
+ Correction_prompt += f'The following error is encountered : {exception}' + '\n'
271
+ Correction_prompt += "You have to give the corrected solution to the product manager's query by modifying the provided JSON. You have to remove the error and only output the corrected JSON."
272
+ return Correction_prompt
273
+
274
+ def placeholder_check(json_response):
275
+ argument_names = []
276
+ if type(json_response) is dict:
277
+ l = []
278
+ l.append(json_response)
279
+ json_response = l
280
+ for item in json_response:
281
+ # try:
282
+ arguments = item.get("arguments", [])
283
+ for argument in arguments:
284
+ # try:
285
+ argument_name = argument.get("argument_name", [])
286
+ argument_value = argument["argument_value"]
287
+ x = re.search("<.*>", str(argument_value))
288
+ if x:
289
+ return 1
290
+ # except KeyError:
291
+ # return 1
292
+ # except AttributeError:
293
+ # return 0
294
+ return 0
295
+
296
+
297
+ def unsolvable_check(json_response):
298
+ for item in json_response:
299
+ for key in item:
300
+ if type(item[key]) is list:
301
+ return 0
302
+ arg = item[key]
303
+ x = re.search(".*cannot.*", arg)
304
+ if x:
305
+ return 1
306
+ return 0
307
+
308
+ def complexity(output):
309
+ num_tools = 0
310
+ num_args = 0
311
+ tool_wt = 2
312
+ args_wt = 0.5
313
+ for tool in output:
314
+ num_tools += 1
315
+ arguments = tool.get("arguments", [])
316
+ for argument in arguments:
317
+ num_args += 1
318
+ return num_args*args_wt + num_tools*tool_wt
319
+
320
+ def structure_check(json_response):
321
+ if type(json_response) is dict:
322
+ l = []
323
+ l.append(json_response)
324
+ json_response = l
325
+ for i, item in enumerate(json_response): #fixing tool_name issue
326
+ if 'tool_name' not in item:
327
+ if type(item) is dict:
328
+ first_key = list(item.keys())[0]
329
+ first_value = item.pop(first_key)
330
+ # Create a new dictionary with 'tool_name' and the rest of the key-value pairs
331
+ new_item = {'tool_name': first_value, **item}
332
+ json_response[i] = new_item
333
+ else:
334
+ item = 'tool_name'
335
+
336
+
337
+ restructured_json = []
338
+ for item in json_response:
339
+ d = {}
340
+ d['tool_name'] = item['tool_name']
341
+ x=[]
342
+ try:
343
+ for args in item['arguments']:
344
+ d_ = {}
345
+ d_['argument_name'] = args['argument_name']
346
+ d_['argument_value'] = args['argument_value']
347
+ x.append(d_)
348
+ d['arguments'] = x
349
+ restructured_json.append(d)
350
+ except (KeyError, TypeError) as e:
351
+ if 'arguments' in item:
352
+ if type(item['arguments']) is not list:
353
+ x = []
354
+ x.append(item['arguments'])
355
+ item['arguments'] = x
356
+ # print(item['arguments'])]
357
+
358
+ for args in item['arguments']:
359
+ # print(args)
360
+ x_ = []
361
+ n = {}
362
+ keys = list(args.keys())
363
+ # print(keys)
364
+ for j in keys:
365
+ d_ = {}
366
+ d_['argument_name'] = j
367
+ d_['argument_value'] = item['arguments'][0][j]
368
+ # print(d_)
369
+ x_.append(d_)
370
+ n['tool_name'] = item['tool_name']
371
+ n['arguments'] = x_
372
+ restructured_json.append(n)
373
+ else:
374
+ pass
375
+
376
+ print(restructured_json)
377
+ return restructured_json
imports.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import json
3
+ import os
4
+ import time
5
+ import random
6
+ import warnings
7
+ import simplejson as json
8
+ import pandas as pd
9
+ import re
10
+ import ast
11
+ from langchain.prompts import PromptTemplate
12
+ from langchain.chains import LLMChain
13
+ from langchain.memory import ConversationBufferWindowMemory
14
+ from langchain_community.chat_models import ChatOpenAI
15
+ from langchain_community.llms import HuggingFaceHub
16
+ from langchain_community.document_loaders import CSVLoader
17
+ from langchain_huggingface import HuggingFaceEmbeddings
18
+ from langchain_community.vectorstores import FAISS
19
+ from langchain.schema.document import Document
20
+ from langfuse.callback import CallbackHandler
mem_check.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from imports import *
2
+
3
+ # Function to verify follow-up queries
4
+
5
+ def verify_follow_up_query(mem_response):
6
+
7
+ classification_index = mem_response.find("Classification:")
8
+ extracted_part = mem_response[classification_index:].split("\n", 1)[0]
9
+ extracted_text = extracted_part.replace("Classification:", "").strip()
10
+ if(extracted_text=="Follow-up"):
11
+ return True
12
+ return False
pipelines.py ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from imports import *
2
+ from hal_check import *
3
+ from prompt_templates import *
4
+ from api_json_to_doc import *
5
+ from mem_check import *
6
+
7
+
8
+
9
+ def dynamic_k(query):
10
+ word_count = len(query.split())
11
+ if word_count <= 7:
12
+ k = 1
13
+ elif word_count <= 15:
14
+ k = 2
15
+ else:
16
+ k = 3
17
+ return k
18
+
19
+ def pipeline(query, API_LIST, available_tools, available_arguments, arg_allowed_values_dict, args_in_list_dict, vector_db):
20
+ print(f"PreviousQuery: {st.session_state.PREV_QUERY}")
21
+ print(f"PreviousResponse: {st.session_state.PREV_RESPONSE}")
22
+ print(f"PastQuery: {st.session_state.PAST_QUERY}")
23
+ print(f"PastResponse: {st.session_state.PAST_RESPONSE}")
24
+ API_LIST = convert_json_to_doc(API_LIST)
25
+ done = False
26
+ max_reprompts = 1
27
+ cntr = 1
28
+ num_examples = dynamic_k(query)
29
+ docs = vector_db.max_marginal_relevance_search(query, k = num_examples)
30
+ RAG_examples = ''
31
+ for i in range(num_examples):
32
+ RAG_examples += f'{docs[i].page_content}' + '\n'
33
+ classification = False
34
+ if(st.session_state.PREV_QUERY!=""):
35
+ if(st.session_state.PAST_QUERY=="NO PAST QUERIES"):
36
+ mem_resp = mem_chain.run(QUERY = query, PREV_QUERY = st.session_state.PREV_QUERY)
37
+ else:
38
+ mem_resp = mem_chain.run(QUERY = query, PREV_QUERY = st.session_state.PAST_QUERY)
39
+
40
+ print(f"0. Memory output- {cntr} ##################")
41
+ print(mem_resp)
42
+ print(f"##################")
43
+ classification = verify_follow_up_query(mem_resp)
44
+ if(classification==False):
45
+ st.session_state.PAST_QUERY = "NO PAST QUERIES"
46
+ st.session_state.PAST_RESPONSE = "NO PAST RESPONSES"
47
+ try:
48
+ resp1 = query_chain.run(QUERY = query , API_LIST = API_LIST, RAG = RAG_examples)
49
+ except:
50
+ return []
51
+ print(f"1. Pseudo code output- {cntr} ##################")
52
+ print(resp1)
53
+ print(type(resp1))
54
+ print(len(resp1))
55
+ print(f"##################")
56
+
57
+
58
+ else:
59
+ if(st.session_state.PAST_RESPONSE =="NO PAST RESPONSES"):
60
+ st.session_state.PAST_QUERY = st.session_state.PREV_QUERY
61
+ st.session_state.PAST_RESPONSE = st.session_state.PREV_RESPONSE
62
+ try:
63
+ resp2 = query_chain_memory.run(QUERY = query , API_LIST = API_LIST, RAG = RAG_examples, PAST_QUERY= st.session_state.PAST_QUERY, PAST_RESPONSE = st.session_state.PAST_RESPONSE)
64
+ except:
65
+ return resp1
66
+ print(f"1. Pseudo code output- {cntr} ##################")
67
+ print(resp2)
68
+ print(type(resp2))
69
+ print(len(resp2))
70
+ print(f"##################")
71
+
72
+ else:
73
+ try:
74
+ resp3 = query_chain.run(QUERY = query , API_LIST = API_LIST, RAG = RAG_examples)
75
+ except:
76
+ return []
77
+ print(f"1. Pseudo code output- {cntr} ##################")
78
+ print(resp3)
79
+ print(type(resp3))
80
+ print(len(resp3))
81
+ print(f"##################")
82
+ # json_response = []
83
+ # try:
84
+ # # Extract json via python code
85
+ # pass
86
+ # except:
87
+ try:
88
+ # print(memory.load_memory_variables({})['chat_history'])
89
+ # chat_history_temp = memory.load_memory_variables({})['chat_history'][1]
90
+ # print(chat_history_temp)
91
+ # memory.load_memory_variables({})['chat_history'] = chat_history_temp
92
+ resp_formatted= format_chain.run(QUERY = "")
93
+ except:
94
+ try:
95
+ return resp3
96
+ except:
97
+ return resp2
98
+ print(f"2. JSON string output- {cntr} ##################")
99
+ print(resp_formatted)
100
+ print(type(resp_formatted))
101
+ print(len(resp_formatted))
102
+ print(f"##################")
103
+ print(f"Reprompt Number: {cntr} #################")
104
+
105
+ print(f"Response formatted:{resp_formatted}")
106
+ try:
107
+ json_response = ast.literal_eval(resp_formatted)
108
+ except Exception as e:
109
+ Correction_prompt = correction_if_wrong_schema(e, resp_formatted)
110
+ resp_formatted = reprompt_chain.run(QUERY=query, API_LIST=API_LIST, CORRECTION_PROMPT=Correction_prompt)
111
+ try:
112
+ json_response = ast.literal_eval(resp_formatted)
113
+ except:
114
+ return []
115
+ print(f"3. JSON decoded output- {cntr} ##################")
116
+ print(json_response)
117
+ print(type(json_response))
118
+ print(len(json_response))
119
+ print(f"##################")
120
+
121
+
122
+ json_response_init = json_response
123
+
124
+ try:
125
+ while not done:
126
+ # hall = True
127
+ try:
128
+ hallucinated_args, hallucinated_tools, hallucinated_args_values, hallucinated_args_values_prev = find_hallucinations(json_response, arg_allowed_values_dict, available_tools, available_arguments, args_in_list_dict)
129
+ except:
130
+ return json_response_init
131
+ print('##############')
132
+ print(f'wrong stuff : {hallucinated_args}, {hallucinated_tools}, {hallucinated_args_values}, {hallucinated_args_values_prev}')
133
+ print('#############')
134
+ if ((len(hallucinated_args) + len(hallucinated_tools) + len(hallucinated_args_values)) + len(hallucinated_args_values_prev) is 0 ):
135
+ if(st.session_state.PREV_QUERY ==""):
136
+ st.session_state.PREV_QUERY = query
137
+ st.session_state.PREV_RESPONSE = str(json_response)
138
+ else:
139
+ if(classification==True):
140
+ st.session_state.PAST_QUERY = st.session_state.PAST_QUERY + '.\n' + query
141
+ st.session_state.PAST_RESPONSE = st.session_state.PAST_RESPONSE + '.\n' + str(json_response)
142
+ st.session_state.PREV_QUERY = query
143
+ st.session_state.PREV_RESPONSE = str(json_response)
144
+ return json_response
145
+ if cntr>max_reprompts:
146
+ done=True
147
+ try:
148
+ Correction_prompt = correction(hallucinated_args, hallucinated_args_values, hallucinated_tools, hallucinated_args_values_prev, json_response)
149
+ except:
150
+ return json_response_init
151
+ print(f"4. Correction prompt- {cntr} ##################")
152
+ print(Correction_prompt)
153
+ print(type(Correction_prompt))
154
+ print(len(Correction_prompt))
155
+ print(f"##################")
156
+
157
+ json_response = reprompt_chain.run(QUERY = query, API_LIST = API_LIST, CORRECTION_PROMPT = Correction_prompt)
158
+ try:
159
+ json_response = ast.literal_eval(json_response)
160
+ except Exception as e:
161
+ Correction_prompt = correction_if_wrong_schema(e, json_response)
162
+ json_response = reprompt_chain.run(QUERY=query, API_LIST=API_LIST, CORRECTION_PROMPT=Correction_prompt)
163
+ try:
164
+ json_response = ast.literal_eval(json_response)
165
+ except:
166
+ return []
167
+ cntr+=1
168
+ print(f"4. JSON decoded output- {cntr} ##################")
169
+ print(json_response)
170
+ print(type(json_response))
171
+ print(len(json_response))
172
+ print(f"##################")
173
+ # json_response = structure_check(json_response)
174
+ if placeholder_check(json_response):
175
+ if(classification==True):
176
+ st.session_state.PAST_QUERY = st.session_state.PAST_QUERY + '.\n' + query
177
+ st.session_state.PAST_RESPONSE = st.session_state.PAST_RESPONSE + '.\n' + '[]'
178
+ st.session_state.PREV_QUERY = query
179
+ st.session_state.PREV_RESPONSE = '[]'
180
+ return []
181
+
182
+ if unsolvable_check(json_response):
183
+ if(classification==True):
184
+ st.session_state.PAST_QUERY = st.session_state.PAST_QUERY + '.\n' + query
185
+ st.session_state.PAST_RESPONSE = st.session_state.PAST_RESPONSE + '.\n' + '[]'
186
+ st.session_state.PREV_QUERY = query
187
+ st.session_state.PREV_RESPONSE = '[]'
188
+ return []
189
+
190
+ if(st.session_state.PREV_QUERY ==""):
191
+ st.session_state.PREV_QUERY = query
192
+ st.session_state.PREV_RESPONSE = str(json_response)
193
+ else:
194
+ if(classification==True):
195
+ st.session_state.PAST_QUERY = st.session_state.PAST_QUERY + '.\n' + query
196
+ st.session_state.PAST_RESPONSE = st.session_state.PAST_RESPONSE + '.\n' + str(json_response)
197
+ st.session_state.PREV_QUERY = query
198
+ st.session_state.PREV_RESPONSE = str(json_response)
199
+ except:
200
+ return json_response_init
201
+ return json_response
prompt_templates.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from imports import *
2
+ from prompts import *
3
+
4
+
5
+ os.environ['HUGGINGFACEHUB_API_TOKEN'] = "<API>"
6
+ os.environ['OPENAI_API_KEY'] = "<API>"
7
+ # ENV_HOST = "https://cloud.langfuse.com"
8
+ # ENV_SECRET_KEY = userdata.get('LF-SECRET')
9
+ # ENV_PUBLIC_KEY = userdata.get('LF-PUBLIC')
10
+
11
+ system_prompt_classifier = PromptTemplate(
12
+ input_variables=["QUERY", "PREV_QUERY"], template= system_prompt_classifier_template,
13
+ output_key="cassification"
14
+ )
15
+
16
+ system_memory_prompt = PromptTemplate(
17
+ input_variables=["QUERY", "API_LIST", "RAG", "PAST_QUERY", "PAST_RESPONSE"], template= system_prompt_memory_template
18
+ )
19
+
20
+ system_prompt = PromptTemplate(
21
+ input_variables=["QUERY", "API_LIST", "RAG"], template= system_prompt_template
22
+ )
23
+
24
+ follow_up_prompt = PromptTemplate(
25
+ input_variables=["QUERY", "chat_history"], template= follow_up_prompt_template
26
+ )
27
+ generation_prompt = PromptTemplate(
28
+ input_variables = ["API_LIST", "FEW_SHOT", "MODIFIED_ARG"],template = generation_prompt_template
29
+ )
30
+
31
+ memory = ConversationBufferWindowMemory(
32
+ memory_key="chat_history", input_key = "QUERY", k = 1,
33
+ return_messages=True
34
+ )
35
+ llm_gpt_3_5 = ChatOpenAI(temperature = 0.0, model = "gpt-3.5-turbo-1106")
36
+ llm_gpt_4 = ChatOpenAI(temperature = 0.0, model = "gpt-4")
37
+
38
+ mem_chain = LLMChain(llm=llm_gpt_3_5,
39
+ prompt=system_prompt_classifier,
40
+ memory = memory,
41
+ verbose=True)
42
+
43
+ query_chain_memory = LLMChain(llm=llm_gpt_3_5,
44
+ prompt=system_memory_prompt,
45
+ memory = memory,
46
+ verbose=True)
47
+
48
+ query_chain = LLMChain(llm=llm_gpt_3_5,
49
+ prompt=system_prompt,
50
+ memory = memory,
51
+ verbose=True)
52
+
53
+ format_chain = LLMChain(llm=llm_gpt_3_5,
54
+ prompt=follow_up_prompt,
55
+ memory = memory,
56
+ verbose=True)
57
+
58
+ generation_chain = LLMChain(llm= ChatOpenAI(temperature = 0.7, model = "gpt-4"),
59
+ prompt=generation_prompt,
60
+ output_key = 'QUERY',
61
+ verbose=False)
62
+ reprompt = PromptTemplate(
63
+ input_variables=["QUERY", "API_LIST", "CORRECTION_PROMPT", "chat_history"], template= reprompt_template
64
+ )
65
+
66
+ reprompt_chain = LLMChain(llm=llm_gpt_4,
67
+ prompt=reprompt,
68
+ output_key = 'new_response',
69
+ memory = memory,
70
+ verbose=True)
prompts.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ system_prompt_classifier_template = '''You are an AI Assistant that specializes in Agile Software Development and Product Management and your task is to assist product managers.\n
2
+
3
+ Objective: Determine if the current user query is a follow-up to previous queries/conversation in a developer/product management context.\n
4
+
5
+ Instructions:\n
6
+ 1. Analyze it in the context of the previous query (provided for reference)..\n
7
+ 2. Classify the current query as either a "Follow-up" or "New Query".\n
8
+ 3. Provide a brief explanation for your classification.\n\n
9
+
10
+
11
+ Your Task:\n
12
+ Previous Query: {PREV_QUERY}\n
13
+ Current Query: {QUERY}\n
14
+ Classification: [Follow-up/New Query]\n
15
+ Explanation: [Your reasoning]
16
+ '''
17
+
18
+ system_prompt_memory_template = '''You are an AI Assistant that specializes in Agile Software Development and Product Management and your task is to assist product managers by providing a list of APIs that can solve the given task using only the APIs given below.\n
19
+
20
+ Below is a list of APIs with their descriptions. Each API has a name, description and a set of arguments. Each argument has a name, description and type.\n\n
21
+
22
+ LIST OF API BEGINS\n
23
+
24
+ {API_LIST}
25
+ \n
26
+
27
+ LIST OF API ENDS\n\n
28
+
29
+ Now in the following conversation, the product manager will ask you to implement certain tasks.\n
30
+ Here are the previous queries and responses that the product manager has asked you to solve. To solve the current query and use for tools or arguments, you can extract any information from these past queries and responses.\n\n
31
+
32
+ Previous Queries: {PAST_QUERY}\n
33
+ Previous Corresponding Responses: {PAST_RESPONSE}\n\n
34
+
35
+ Now, the final output by you, the AI assistant, should be an ordered list of zero or more API's and their corresponding arguments that are needed to solve the task.\n\b
36
+
37
+ Keep in mind that:\n
38
+ 1. A task might require multiple APIs to be called.\n
39
+ 2. The output can use an API more than one time.\n
40
+ 3. Each API can have multiple arguments being used.\n
41
+ 4. To reference the value of the ith API in the list, use $$PREV[i] as argument value. i = 0, 1, .. j-1; j = current API’s index in the list.\n
42
+ 5. To answer the current query, you may require infromation from the previous queries. Though, this may not always be the case.\n
43
+
44
+ Also note that: If you cannot solve the task using the given set of functions, state explicitly that the given task can't be solved using the given set of APIs.\n\n
45
+ EXAMPLES BEGIN
46
+
47
+ {RAG}
48
+
49
+ EXAMPLES END\n
50
+
51
+ You can use the previous conversations to fill in the arguments of the current query. Though, you cannot refer to values in previous conversations using '$$PREV[I]'. You have to use them explicitly.\n
52
+
53
+ Query : {QUERY}
54
+
55
+ '''
56
+
57
+
58
+ system_prompt_template = '''You are an AI Assistant that specializes in Agile Software Development and Product Management and your task is to assist product managers by providing a list of APIs that can solve the given task using only the APIs given below.\n
59
+
60
+ Below is a list of APIs with their descriptions. Each API has a name, description and a set of arguments. Each argument has a name, description and type.\n\n
61
+
62
+ LIST OF API BEGINS\n
63
+
64
+ {API_LIST}
65
+ \n
66
+
67
+ LIST OF API ENDS\n
68
+
69
+ Now in the following conversation, the product manager will ask you to implement certain tasks.\n
70
+
71
+ The output by you, the AI assistant, should be an ordered list of zero or more API's and their corresponding arguments that are needed to solve the task.\n\n
72
+
73
+ Keep in mind that:\n
74
+ 1. A task might require multiple APIs to be called.\n
75
+ 2. The output can use an API more than one time.\n
76
+ 3. Each API can have multiple arguments being used.\n
77
+ 4. To reference the value of the ith API in the list, use $$PREV[i] as argument value. i = 0, 1, .. j-1; j = current API’s index in the list.\n
78
+
79
+ Note that: If you cannot solve the task using the given set of functions, state explicitly that the given task can't be solved using the given set of APIs.\n\n
80
+
81
+ EXAMPLES BEGIN\n
82
+
83
+ {RAG}
84
+ \n
85
+ EXAMPLES END\n\n
86
+
87
+
88
+
89
+ Query : {QUERY}
90
+
91
+ '''
92
+
93
+ follow_up_prompt_template = '''
94
+ {chat_history}
95
+ From your solution extract a list of JSONs. Return only the list of JSONs.
96
+ The format for the JSONs:
97
+ {{
98
+ "tool_name": {{ "type": "string" }},
99
+ "arguments": [
100
+ {{
101
+ "argument_name": "{{ "type": "string" }},
102
+ "argument_value": {{ "type": "string" }},
103
+ }}
104
+ ]
105
+ }}
106
+
107
+ If according to your response, the query cannot be solved using the given APIs, return an empty list.
108
+ '''
109
+
110
+ reprompt_template= '''You are an AI Assistant that specializes in Agile Software Development and Product Management and your task is to assist product managers by providing a list of APIs that can solve the given task using only the APIs given below.
111
+
112
+ Below is a list of API's with their descriptions. Each API is represented as a dictionary with key value pairs where the keys are “name”, “description”, “arguments”. The value corresponding to the “arguments” key is a list of dictionaries where each dictionary represents an argument. Each argument is represented in the form of a dictionary with key value pairs where the keys are "argument name", "argument description", "argument type".
113
+
114
+ LIST OF API BEGINS
115
+
116
+ {API_LIST}
117
+
118
+ LIST OF API ENDS
119
+
120
+ {QUERY}
121
+
122
+ {chat_history}
123
+
124
+ {CORRECTION_PROMPT}
125
+ '''
126
+ generation_prompt_template = '''You are an AI Assistant that specializes in Agile Software Development and Product Management and your task is to assist product managers by providing a list of APIs that can solve the given task using only the APIs given below.
127
+
128
+ Below is a list of APIs with their descriptions. Each API has a name, description and a set of arguments. Each argument has a name, description and type.
129
+
130
+ LIST OF API BEGINS
131
+
132
+ {API_LIST}
133
+
134
+ LIST OF API ENDS
135
+
136
+ Keep in mind that:
137
+ 1. A task might require multiple APIs to be called.
138
+ 2. The output can use an API more than one time.
139
+ 3. There can be multiple APIs that are used.
140
+ 4. Each API can have multiple arguments being used.
141
+ 5. To reference the value of the ith API in the list, use $$PREV[i] as argument value. i = 0, 1, .. j-1; j = current API’s index in the list.
142
+
143
+ A few examples of a query are:
144
+
145
+ {FEW_SHOT}
146
+
147
+ {MODIFIED_ARG}
148
+
149
+ {{QUERY: , REASONING: }}
150
+ '''
requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ openai<1.0.0
3
+ langchain
4
+ huggingface_hub
5
+ tiktoken
6
+ cohere
7
+ langfuse
8
+ chromadb
9
+ sentence_transformers
10
+ simplejson
11
+ faiss-cpu
retrieval.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from imports import *
2
+
3
+ loader = CSVLoader(file_path=r'Seed_Dataset.csv')
4
+ data = loader.load()
5
+
6
+ embeddings = HuggingFaceEmbeddings()
7
+ # persist_directory = 'docs/chroma_db/'
8
+ # !rm -rf ./docs/chroma_db
9
+ vector_db = FAISS.from_documents(
10
+ documents=data,
11
+ embedding=embeddings,
12
+ # persist_directory=persist_directory
13
+ )
14
+ # vector_db.persist()
15
+
16
+ def store_to_df(store):
17
+ v_dict = store.docstore._dict
18
+ data_rows = []
19
+ for k in v_dict.keys():
20
+ content = v_dict[k].page_content
21
+ data_rows.append({"chunk_id" : k, "content" : content})
22
+ vector_df = pd.DataFrame(data_rows)
23
+ return vector_df
24
+
25
+ def show_vstore(store):
26
+ vector_df = store_to_df(store)
27
+ # display(vector_df)
28
+
29
+ def delete_tool_examples(store, tool_name, arg_name = None):
30
+ vector_df = store_to_df(store)
31
+ if (arg_name is not None):
32
+ mask = (vector_df['content'].str.contains(tool_name) & vector_df['content'].str.contains(arg_name))
33
+ else:
34
+ mask = vector_df['content'].str.contains(tool_name)
35
+ chunk_ids_to_delete = vector_df.loc[mask, 'chunk_id']
36
+ print(chunk_ids_to_delete)
37
+ try:
38
+ store.delete(chunk_ids_to_delete)
39
+ except:
40
+ print("Unable to delete")
41
+
42
+ def add_to_vector_store(store, examples):
43
+ for example in examples:
44
+ doc = Document(page_content = example)
45
+ extension = FAISS.from_documents([doc], embeddings)
46
+ store.merge_from(extension)
update_api_toolset.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from imports import *
2
+ from retrieval import *
3
+ from prompt_templates import *
4
+ from hal_check import *
5
+
6
+ def API_CHOICE(n, tool_name, api_list):
7
+ l = []
8
+ apis = api_list.copy()
9
+ if tool_name in apis:
10
+ apis.remove(tool_name)
11
+ for i in range(n):
12
+ choice = random.choice(apis)
13
+ apis.remove(choice)
14
+ l.append(choice)
15
+ return l
16
+
17
+ def generate_examples(tool_name, api_list, store, num_examples = 2, arg_name = None):
18
+ APIs = API_CHOICE(2, tool_name, api_list)
19
+ if len(list(store.docstore._dict.values()))>=2:
20
+ few_shot_examples = random.sample(list(store.docstore._dict.values()), 2)
21
+ few_shot_examples = [few_shot_examples[0].page_content, few_shot_examples[1].page_content]
22
+ elif len(list(store.docstore._dict.values()))==1:
23
+
24
+ few_shot_examples = random.sample(list(store.docstore._dict.values()), 1)
25
+ few_shot_examples = [few_shot_examples[0].page_content]
26
+ else:
27
+ few_shot_examples=[]
28
+
29
+ examples = []
30
+ if arg_name is not None:
31
+ MODIFIED_ARG = f'Now you must only use {APIs} and {tool_name} to generate a query, its reasoning and the finar answer. You, also must use the argument {arg_name} for the tool {tool_name} to generate the query. Now generate a query and give your output in the form of the following dictionary.'
32
+ else:
33
+ MODIFIED_ARG = f'Now you must only use {APIs} and {tool_name} to generate a query, its reasoning and the finar answer. Now generate a query and give your output in the form of the following dictionary.'
34
+ for i in range(num_examples):
35
+ examples.append(generation_chain.run(API_LIST = api_list, FEW_SHOT = few_shot_examples, MODIFIED_ARG = MODIFIED_ARG))
36
+ return examples
37
+
38
+ api_weights = {'works_list': 0, 'prioritize_objects' : 0, 'add_work_items_to_sprint' : 0, 'get_sprint_id' : 0, 'get_similar_work_items' : 0, 'search_object_by_name' : 0,
39
+ 'create_actionable_tasks_from_text' : 0, 'who_am_i' : 0, 'get_works_id' : 0, }
40
+
41
+ api_list = list(api_weights.keys())
42
+
43
+ # Function to add a new tool
44
+ def add_tool(api_list, name, description, available_tools, available_arguments, store):
45
+ available_tools.append(name)
46
+ api_list.append({"name": name, "description": description, "arguments": []})
47
+ available_arguments.append(f"{name}/")
48
+ example = generate_examples(name, api_list, store)
49
+ add_to_vector_store(store, example)
50
+ return api_list, available_tools, available_arguments
51
+
52
+ def delete_tool(api_list, tool_name, available_tools, available_arguments, arg_allowed_values_dict, args_in_list_dict, store):
53
+ delete_tool_examples(store, tool_name)
54
+ available_tools.remove(tool_name)
55
+ available_arguments = [s for s in available_arguments if not s.startswith(tool_name)]
56
+ arg_allowed_values_dict = {key: value for key, value in arg_allowed_values_dict.items() if not key.startswith(tool_name)}
57
+ args_in_list_dict = {key: value for key, value in args_in_list_dict.items() if not key.startswith(tool_name)}
58
+ api_list = [tool for tool in api_list if tool['name'] != tool_name]
59
+ return api_list, available_tools, available_arguments, arg_allowed_values_dict, args_in_list_dict, store
60
+
61
+ # Function to update a tool
62
+ def update_tool(api_list, old_tool_name, new_tool_name, new_description, available_tools, available_arguments, arg_allowed_values_dict, args_in_list_dict, store):
63
+ delete_tool_examples(store, old_tool_name)
64
+ for tool in api_list:
65
+ if tool['name'] == old_tool_name:
66
+ tool['name'] = new_tool_name
67
+ tool['description'] = new_description
68
+ break
69
+ example = generate_examples(new_tool_name, api_list, store, num_examples = 4)
70
+ add_to_vector_store(store, example)
71
+ available_tools.remove(old_tool_name)
72
+ available_tools.append(new_tool_name)
73
+ available_arguments = [s.replace(old_tool_name, new_tool_name, 1) if s.startswith(old_tool_name) else s for s in available_arguments]
74
+ keys_to_replace1 = [key for key in arg_allowed_values_dict if key.startswith(old_tool_name)]
75
+ for key in keys_to_replace1:
76
+ new_key = key.replace(old_tool_name, new_tool_name)
77
+ arg_allowed_values_dict[new_key] = arg_allowed_values_dict[key]
78
+ del arg_allowed_values_dict[key]
79
+ keys_to_replace2 = [key for key in args_in_list_dict if key.startswith(old_tool_name)]
80
+ for key in keys_to_replace2:
81
+ new_key = key.replace(old_tool_name, new_tool_name)
82
+ args_in_list_dict[new_key] = args_in_list_dict[key]
83
+ del args_in_list_dict[key]
84
+ return api_list, available_tools, available_arguments, arg_allowed_values_dict, args_in_list_dict
85
+
86
+ # Function to add an argument to a tool
87
+ def add_argument(api_list, tool_name, arg_name, arg_desc, arg_type, arg_allowed_values, available_arguments, arg_allowed_values_dict, args_in_list_dict, store):
88
+ delete_tool_examples(store, tool_name)
89
+ for tool in api_list:
90
+ if tool['name'] == tool_name:
91
+ tool['arguments'].append({
92
+ "argument_name": arg_name,
93
+ "argument_description": arg_desc,
94
+ "argument_type": arg_type
95
+ })
96
+ break
97
+ if 'array' in arg_type.lower() :
98
+ args_in_list_dict[f'{tool_name}/{arg_name}'] = 1
99
+ else:
100
+ args_in_list_dict[f'{tool_name}/{arg_name}'] = 0
101
+ example = generate_examples(tool_name, api_list, store, num_examples = 4)
102
+ add_to_vector_store(store, example)
103
+ available_arguments.append(f"{tool_name}/{arg_name}")
104
+ if len(arg_allowed_values) is not 0:
105
+ arg_allowed_values_dict[f'{tool_name}/{arg_name}'] = ast.literal_eval(arg_allowed_values)
106
+ return api_list, available_arguments, arg_allowed_values_dict, args_in_list_dict
107
+
108
+ # Function to delete an argument from a tool
109
+ def delete_argument(api_list, tool_name, arg_name, available_arguments, arg_allowed_values_dict, args_in_list_dict, store):
110
+ delete_tool_examples(store, tool_name, arg_name)
111
+ for tool in api_list:
112
+ if tool['name'] == tool_name:
113
+ tool['arguments'] = [arg for arg in tool['arguments'] if arg['argument_name'] != arg_name]
114
+ break
115
+ examples = generate_examples(tool_name, api_list, store)
116
+ add_to_vector_store(store, examples)
117
+ arg_to_delete = f"{tool_name}/{arg_name}"
118
+ available_arguments.remove(arg_to_delete)
119
+ if arg_to_delete in arg_allowed_values_dict:
120
+ del arg_allowed_values_dict[arg_to_delete]
121
+ if arg_to_delete in args_in_list_dict:
122
+ del args_in_list_dict[arg_to_delete]
123
+ return api_list, available_arguments, arg_allowed_values_dict, args_in_list_dict
124
+
125
+ # Function to update an argument
126
+ def update_argument(api_list, tool_name, old_arg_name, new_arg_name, new_arg_desc, new_arg_type, new_arg_allowed_values, available_arguments, arg_allowed_values_dict, args_in_list_dict, store):
127
+ delete_tool_examples(store, tool_name, old_arg_name)
128
+ for tool in api_list:
129
+ if tool['name'] == tool_name:
130
+ for arg in tool['arguments']:
131
+ if arg['argument_name'] == old_arg_name:
132
+ arg['argument_name'] = new_arg_name
133
+ arg['argument_description'] = new_arg_desc
134
+ arg['argument_type'] = new_arg_type
135
+ break
136
+ break
137
+ examples = generate_examples(tool_name, api_list, store, arg_name = new_arg_name)
138
+ add_to_vector_store(store, examples)
139
+ available_arguments.remove(f"{tool_name}/{old_arg_name}")
140
+ available_arguments.append(f"{tool_name}/{new_arg_name}")
141
+ if f"{tool_name}/{old_arg_name}" in arg_allowed_values_dict:
142
+ del arg_allowed_values_dict[f"{tool_name}/{old_arg_name}"]
143
+ if f"{tool_name}/{old_arg_name}" in args_in_list_dict:
144
+ del args_in_list_dict[f"{tool_name}/{old_arg_name}"]
145
+ if len(new_arg_allowed_values) is not 0:
146
+ arg_allowed_values_dict[f'{tool_name}/{new_arg_name}'] = ast.literal_eval(new_arg_allowed_values)
147
+ if 'array' in new_arg_type.lower() :
148
+ args_in_list_dict[f'{tool_name}/{new_arg_name}'] = 1
149
+ else:
150
+ args_in_list_dict[f'{tool_name}/{new_arg_name}'] = 0
151
+ return api_list, available_arguments, arg_allowed_values_dict, args_in_list_dict
152
+
153
+ # Function to delete multiple arguments from a tool
154
+ def delete_multiple_arguments(api_list, tool_name, arg_names, available_arguments, arg_allowed_values_dict, args_in_list_dict, store):
155
+ for arg_name in arg_names :
156
+ delete_tool_examples(store, tool_name, arg_name)
157
+ arg_to_delete = f"{tool_name}/{arg_name}"
158
+ available_arguments.remove(arg_to_delete)
159
+ if arg_to_delete in arg_allowed_values_dict:
160
+ del arg_allowed_values_dict[arg_to_delete]
161
+ if arg_to_delete in args_in_list_dict:
162
+ del args_in_list_dict[arg_to_delete]
163
+ for tool in api_list:
164
+ if tool['name'] == tool_name:
165
+ tool['arguments'] = [arg for arg in tool['arguments'] if arg['argument_name'] not in arg_names]
166
+ break
167
+ examples = generate_examples(tool_name, api_list, store)
168
+ add_to_vector_store(store, examples)
169
+ return api_list, available_arguments, arg_allowed_values_dict, args_in_list_dict