99from gooddata_api_client .model .chat_history_result import ChatHistoryResult
1010from gooddata_api_client .model .chat_request import ChatRequest
1111from gooddata_api_client .model .chat_result import ChatResult
12+ from gooddata_api_client .model .search_request import SearchRequest
13+ from gooddata_api_client .model .search_result import SearchResult
1214
1315from gooddata_sdk .client import GoodDataApiClient
1416from gooddata_sdk .compute .model .execution import Execution , ExecutionDefinition , ResultCacheMetadata
@@ -91,17 +93,27 @@ def ai_chat(self, workspace_id: str, question: str) -> ChatResult:
9193 response = self ._actions_api .ai_chat (workspace_id , chat_request , _check_return_type = False )
9294 return response
9395
94- def ai_chat_history (self , workspace_id : str , chat_history_interaction_id : int = 0 ) -> ChatHistoryResult :
96+ def ai_chat_history (
97+ self , workspace_id : str , chat_history_interaction_id : str = None , thread_id_suffix : str = None
98+ ) -> ChatHistoryResult :
9599 """
96100 Get chat history with AI in GoodData workspace.
97101
98102 Args:
99103 workspace_id: workspace identifier
100- chat_history_interaction_id: collect history starting from this interaction id
104+ chat_history_interaction_id: collect history starting from this interaction id. If None, complete chat history is returned.
105+ thread_id_suffix: suffix to identify a specific chat thread. If provided, chat_history_interaction_id is ignored.
101106 Returns:
102- str : Chat history response
107+ ChatHistoryResult : Chat history response containing interactions and other metadata
103108 """
104- chat_history_request = ChatHistoryRequest (chat_history_interaction_id = chat_history_interaction_id )
109+
110+ if chat_history_interaction_id is None :
111+ chat_history_interaction_id = ""
112+ if thread_id_suffix is None :
113+ thread_id_suffix = ""
114+ chat_history_request = ChatHistoryRequest (
115+ chat_history_interaction_id = chat_history_interaction_id , reset = False , thread_id_suffix = thread_id_suffix
116+ )
105117 response = self ._actions_api .ai_chat_history (workspace_id , chat_history_request , _check_return_type = False )
106118 return response
107119
@@ -115,6 +127,72 @@ def ai_chat_history_reset(self, workspace_id: str) -> None:
115127 chat_history_request = ChatHistoryRequest (reset = True )
116128 self ._actions_api .ai_chat_history (workspace_id , chat_history_request , _check_return_type = False )
117129
130+ def ai_chat_history_feedback (
131+ self , workspace_id : str , user_feedback : str , chat_history_interaction_id : str , thread_id_suffix : str = None
132+ ) -> None :
133+ """
134+ Provide feedback for a specific chat history interaction.
135+
136+ Args:
137+ workspace_id: workspace identifier
138+ user_feedback: feedback to provide ("POSITIVE", "NEGATIVE" or "NONE")
139+ chat_history_interaction_id: interaction id to provide feedback for
140+ thread_id_suffix: suffix to identify a specific chat thread
141+ """
142+ if thread_id_suffix is None :
143+ thread_id_suffix = ""
144+ chat_history_request = ChatHistoryRequest (
145+ user_feedback = user_feedback ,
146+ chat_history_interaction_id = chat_history_interaction_id ,
147+ thread_id_suffix = thread_id_suffix ,
148+ reset = False ,
149+ )
150+ self ._actions_api .ai_chat_history (workspace_id , chat_history_request , _check_return_type = False )
151+
152+ def ai_search (
153+ self ,
154+ workspace_id : str ,
155+ question : str ,
156+ deep_search : bool = None ,
157+ limit : int = None ,
158+ object_types : list [str ] = None ,
159+ relevant_score_threshold : float = None ,
160+ title_to_descriptor_ratio : float = None ,
161+ ) -> SearchResult :
162+ """
163+ Search for metadata objects using similarity search.
164+
165+ Args:
166+ workspace_id: workspace identifier
167+ question: keyword/sentence input for search
168+ deep_search: turn on deep search - if true, content of complex objects will be searched as well
169+ limit: maximum number of results to return
170+ object_types: list of object types to search for. Enum items: "attribute", "metric", "fact",
171+ "label", "date", "dataset", "visualization" and "dashboard"
172+ relevant_score_threshold: minimum relevance score threshold for results
173+ title_to_descriptor_ratio: ratio of title score to descriptor score
174+
175+ Returns:
176+ SearchResult: Search results
177+
178+ Note:
179+ Default values for optional parameters are documented in the AI Search endpoint of the GoodData API.
180+ """
181+ search_params = {}
182+ if deep_search is not None :
183+ search_params ["deep_search" ] = deep_search
184+ if limit is not None :
185+ search_params ["limit" ] = limit
186+ if object_types is not None :
187+ search_params ["object_types" ] = object_types
188+ if relevant_score_threshold is not None :
189+ search_params ["relevant_score_threshold" ] = relevant_score_threshold
190+ if title_to_descriptor_ratio is not None :
191+ search_params ["title_to_descriptor_ratio" ] = title_to_descriptor_ratio
192+ search_request = SearchRequest (question = question , ** search_params )
193+ response = self ._actions_api .ai_search (workspace_id , search_request , _check_return_type = False )
194+ return response
195+
118196 def cancel_executions (self , executions : dict [str , dict [str , str ]]) -> None :
119197 """
120198 Try to cancel given executions using the cancel api endpoint.
@@ -132,3 +210,13 @@ def cancel_executions(self, executions: dict[str, dict[str, str]]) -> None:
132210 )
133211 except ApiException as e :
134212 print ("Exception when calling ActionsApi->cancel_executions: %s\n " , e )
213+
214+ def metadata_sync (self , workspace_id : str , async_req : bool = False ) -> None :
215+ """
216+ Sync metadata to other services.
217+
218+ Args:
219+ workspace_id: workspace identifier
220+ async_req: if True, the metadata sync will be performed asynchronously
221+ """
222+ self ._actions_api .metadata_sync (workspace_id , async_req = async_req , _check_return_type = False )
0 commit comments