glchat-plugin 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,126 @@
1
+ """Base Pipeline Builder Plugin.
2
+
3
+ This module defines the base class for pipeline builder plugins.
4
+
5
+ Authors:
6
+ Samuel Lusandi (samuel.lusandi@gdplabs.id)
7
+ Hermes Vincentius Gani (hermes.v.gani@gdplabs.id)
8
+ """
9
+
10
+ from abc import ABC, abstractmethod
11
+ from typing import Any, Generic, Type, TypeVar
12
+
13
+ from bosa_core.plugin.plugin import Plugin
14
+ from gllm_inference.catalog.catalog import BaseCatalog
15
+ from gllm_pipeline.pipeline.pipeline import Pipeline
16
+
17
+ from glchat_plugin.pipeline.pipeline_handler import PipelineHandler
18
+
19
+ PipelineState = TypeVar("PipelineState")
20
+ PipelinePresetConfig = TypeVar("PipelinePresetConfig", bound="BasePipelinePresetConfig")
21
+ PipelineRuntimeConfig = TypeVar("PipelineRuntimeConfig", bound="BaseModel")
22
+
23
+
24
+ @Plugin.for_handler(PipelineHandler)
25
+ class PipelineBuilderPlugin(Plugin, Generic[PipelineState, PipelinePresetConfig], ABC):
26
+ """Base class for pipeline builder plugins.
27
+
28
+ This class combines the Plugin architecture with the Pipeline Builder functionality.
29
+
30
+ Attributes:
31
+ name (str): The name of the plugin.
32
+ description (str): The description of the plugin.
33
+ version (str): The version of the plugin.
34
+ catalog (BaseCatalog): The catalog instance.
35
+ additional_config_class (Type[PipelineRuntimeConfig] | None): The additional runtime configuration class.
36
+ preset_config_class (Type[PipelinePresetConfig] | None): The preset configuration class.
37
+ """
38
+
39
+ name: str
40
+ description: str = "Pipeline builder plugin"
41
+ version: str = "0.0.0"
42
+
43
+ catalog: BaseCatalog[Any]
44
+
45
+ additional_config_class: Type[PipelineRuntimeConfig] | None = None
46
+ preset_config_class: Type[PipelinePresetConfig] | None = None
47
+
48
+ @classmethod
49
+ def get_preset_config_class(cls) -> Type[PipelinePresetConfig]:
50
+ """Get the preset_config_class.
51
+
52
+ Returns:
53
+ Type[PipelinePresetConfig]: The pipeline preset config class.
54
+
55
+ Raises:
56
+ NotImplementedError: If the preset_config_class is not defined.
57
+ """
58
+ if cls.preset_config_class is None:
59
+ raise NotImplementedError(f"{cls.__name__} must define a `preset_config_class` attribute.")
60
+ return cls.preset_config_class
61
+
62
+ @abstractmethod
63
+ def build_initial_state(
64
+ self,
65
+ request_config: dict[str, Any],
66
+ pipeline_config: dict[str, Any],
67
+ **kwargs: Any,
68
+ ) -> PipelineState:
69
+ """Build the initial pipeline state.
70
+
71
+ Args:
72
+ request_config (dict[str, Any]): Request configuration.
73
+ pipeline_config (dict[str, Any]): Pipeline configuration.
74
+ kwargs (Any): Additional state arguments.
75
+
76
+ Returns:
77
+ PipelineState: Initial pipeline state.
78
+ """
79
+ pass
80
+
81
+ @abstractmethod
82
+ async def build(
83
+ self,
84
+ pipeline_config: dict[str, Any],
85
+ ) -> Pipeline:
86
+ """Build a pipeline instance.
87
+
88
+ Args:
89
+ pipeline_config (dict[str, Any]): Pipeline configuration including model name and other settings.
90
+
91
+ Returns:
92
+ Pipeline: Built pipeline instance.
93
+ """
94
+ pass
95
+
96
+ async def cleanup(self):
97
+ """Cleanup the pipeline resources, if needed."""
98
+ pass
99
+
100
+ def build_additional_runtime_config(
101
+ self,
102
+ pipeline_config: dict[str, Any],
103
+ ) -> dict[str, Any]:
104
+ """Build additional runtime configuration.
105
+
106
+ Args:
107
+ pipeline_config (dict[str, Any]): Pipeline configuration.
108
+
109
+ Returns:
110
+ dict[str, Any]: Additional runtime configuration.
111
+ """
112
+ if not self.additional_config_class:
113
+ return {}
114
+
115
+ config = self.additional_config_class(**pipeline_config)
116
+ return config.model_dump(exclude_none=True)
117
+
118
+ def get_config(self) -> dict[str, Any]:
119
+ """Get the pipeline configuration.
120
+
121
+ Returns:
122
+ dict[str, Any]: Pipeline configuration.
123
+ """
124
+ if self.preset_config_class:
125
+ return self.preset_config_class().model_dump()
126
+ return {}
@@ -0,0 +1 @@
1
+ """Module for glchat_plugin user service."""
@@ -0,0 +1,82 @@
1
+ """Provides a base class for user service.
2
+
3
+ Authors:
4
+ Immanuel Rhesa (immanuel.rhesa@gdplabs.id)
5
+ Hermes Vincentius Gani (hermes.v.gani@gdplabs.id)
6
+
7
+ References:
8
+ NONE
9
+ """
10
+
11
+ from abc import ABC, abstractmethod
12
+ from typing import Any
13
+
14
+
15
+ class BaseUserService(ABC):
16
+ """A base class for user service."""
17
+
18
+ @abstractmethod
19
+ async def get_user_id(self, **kwargs: Any) -> str:
20
+ """Abstract method to get the user id.
21
+
22
+ Args:
23
+ **kwargs (Any): Additional keyword arguments for user identification.
24
+
25
+ Returns:
26
+ str: user id.
27
+
28
+ Raises:
29
+ NotImplementedError: If the method is not implemented.
30
+ """
31
+ raise NotImplementedError
32
+
33
+ @abstractmethod
34
+ async def register(self, **kwargs: Any):
35
+ """Abstract method to register a new user.
36
+
37
+ Args:
38
+ **kwargs (Any): Additional keyword arguments for user registration.
39
+
40
+ Raises:
41
+ NotImplementedError: If the method is not implemented.
42
+ """
43
+ raise NotImplementedError
44
+
45
+ @abstractmethod
46
+ async def login(self, **kwargs: Any):
47
+ """Abstract method to authenticate and login a user.
48
+
49
+ Args:
50
+ **kwargs (Any): Additional keyword arguments for user login.
51
+
52
+ Raises:
53
+ NotImplementedError: If the method is not implemented.
54
+ """
55
+ raise NotImplementedError
56
+
57
+ @abstractmethod
58
+ async def get_applications(self, **kwargs: Any) -> Any:
59
+ """Abstract method to get user applications.
60
+
61
+ Args:
62
+ **kwargs (Any): Additional keyword arguments for retrieving applications.
63
+
64
+ Returns:
65
+ Any: User applications data.
66
+
67
+ Raises:
68
+ NotImplementedError: If the method is not implemented.
69
+ """
70
+ raise NotImplementedError
71
+
72
+ @abstractmethod
73
+ async def set_user_applications(self, **kwargs: Any):
74
+ """Abstract method to set user applications.
75
+
76
+ Args:
77
+ **kwargs (Any): Additional keyword arguments for setting user applications.
78
+
79
+ Raises:
80
+ NotImplementedError: If the method is not implemented.
81
+ """
82
+ raise NotImplementedError
@@ -0,0 +1 @@
1
+ """Module for glchat_plugin storage interface."""
@@ -0,0 +1,58 @@
1
+ """Interface for Anonymizer Storage.
2
+
3
+ Authors:
4
+ Hermes Vincentius Gani (hermes.v.gani@gdplabs.id)
5
+
6
+ References:
7
+ None
8
+ """
9
+
10
+ from abc import ABC, abstractmethod
11
+ from typing import TypeVar
12
+
13
+ AnonymizerMapping = TypeVar("AnonymizerMapping")
14
+ MappingDataType = TypeVar("MappingDataType")
15
+
16
+
17
+ class BaseAnonymizerStorage(ABC):
18
+ """Interface for anonymizer storage that defines methods for managing anonymizer mappings."""
19
+
20
+ @abstractmethod
21
+ def get_mappings_by_conversation_id(self, conversation_id: str) -> list[AnonymizerMapping]:
22
+ """Retrieve anonymizer mappings by conversation ID.
23
+
24
+ Args:
25
+ conversation_id (str): The ID of the conversation.
26
+
27
+ Returns:
28
+ list[AnonymizerMapping]: A list of anonymizer mappings associated with the conversation ID.
29
+ """
30
+ pass
31
+
32
+ @abstractmethod
33
+ def create_mapping(
34
+ self, conversation_id: str, pii_type: str, anonymized_value: str, pii_value: str
35
+ ) -> AnonymizerMapping:
36
+ """Create a new anonymizer mapping.
37
+
38
+ Args:
39
+ conversation_id (str): The ID of the conversation.
40
+ pii_type (str): The type of personally identifiable information (PII).
41
+ anonymized_value (str): The anonymized value of the PII.
42
+ pii_value (str): The original PII value.
43
+
44
+ Returns:
45
+ AnonymizerMapping: The created anonymizer mapping.
46
+ """
47
+ pass
48
+
49
+ @abstractmethod
50
+ def update_mapping(self, conversation_id: str, is_anonymized: bool, mapping_data_type: MappingDataType) -> None:
51
+ """Update the mappings for a specific conversation with new anonymizer mappings.
52
+
53
+ Args:
54
+ conversation_id (str): The unique identifier for the conversation.
55
+ is_anonymized (bool): The flag to determine if the message is anonymized.
56
+ mapping_data_type (MappingDataType): A dictionary of new anonymizer mappings to update for deanonymization.
57
+ """
58
+ pass
@@ -0,0 +1,356 @@
1
+ """Interface for Chat History Storage.
2
+
3
+ Authors:
4
+ Hermes Vincentius Gani (hermes.v.gani@gdplabs.id)
5
+
6
+ References:
7
+ None
8
+ """
9
+
10
+ from abc import ABC, abstractmethod
11
+ from datetime import datetime
12
+ from enum import StrEnum
13
+ from typing import Any
14
+
15
+ from typing_extensions import TypeVar
16
+
17
+ from glchat_plugin.storage.base_anonymizer_storage import AnonymizerMapping
18
+
19
+ Conversation = TypeVar("Conversation")
20
+ Message = TypeVar("Message")
21
+ ConversationDocument = TypeVar("ConversationDocument")
22
+
23
+
24
+ class MessageRole(StrEnum):
25
+ """Enum for Message Type."""
26
+
27
+ USER = "USER"
28
+ AI = "AI"
29
+
30
+
31
+ class DocumentStatus(StrEnum):
32
+ """Enum for ConversationDocument Status."""
33
+
34
+ PROCESSING = "processing"
35
+ DONE = "done"
36
+ FAILED = "failed"
37
+
38
+
39
+ class BaseChatHistoryStorage(ABC):
40
+ """Interface for chat history storage that defines methods for managing chat conversations and messages."""
41
+
42
+ @abstractmethod
43
+ def create_conversation(
44
+ self, user_id: str, conversation_title: str, chatbot_id: str, **kwargs: Any
45
+ ) -> Conversation:
46
+ """Create a new conversation.
47
+
48
+ Args:
49
+ user_id (str): The ID of the user.
50
+ conversation_title (str): The title of the conversation.
51
+ chatbot_id (str): The ID of the chatbot.
52
+ kwargs (Any): Additional arguments.
53
+
54
+ Returns:
55
+ Conversation: The created conversation.
56
+ """
57
+ pass
58
+
59
+ @abstractmethod
60
+ def get_conversation(self, user_id: str, conversation_id: str, **kwargs: Any) -> Conversation | None:
61
+ """Retrieve a specific conversation by its ID.
62
+
63
+ Args:
64
+ user_id (str): The ID of the user.
65
+ conversation_id (str): The ID of the conversation.
66
+ kwargs (Any): Additional arguments.
67
+
68
+ Returns:
69
+ Conversation | None: The conversation if found, otherwise None.
70
+ """
71
+ pass
72
+
73
+ @abstractmethod
74
+ def get_conversations(
75
+ self,
76
+ user_id: str,
77
+ query: str = "",
78
+ chatbot_ids: list[str] | None = None,
79
+ cursor: str | None = None,
80
+ limit: int | None = None,
81
+ **kwargs: Any,
82
+ ) -> list[Conversation]:
83
+ """Retrieve a list of conversations for a user.
84
+
85
+ Args:
86
+ user_id (str): The ID of the user.
87
+ query (str, optional): A search query to filter conversations. Defaults to "".
88
+ chatbot_ids (list[str] | None, optional): A list of chatbot IDs to filter conversations. Defaults to None.
89
+ cursor (str | None, optional): A cursor for pagination. Defaults to None.
90
+ limit (int | None, optional): The maximum number of conversations to retrieve. Defaults to None.
91
+ kwargs (Any): Additional arguments.
92
+
93
+ Returns:
94
+ list[Conversation]: A list of conversations.
95
+ """
96
+ pass
97
+
98
+ @abstractmethod
99
+ def rename_conversation(self, user_id: str, conversation_id: str, new_title: str, **kwargs: Any) -> Conversation:
100
+ """Rename an existing conversation.
101
+
102
+ Args:
103
+ user_id (str): The ID of the user.
104
+ conversation_id (str): The ID of the conversation.
105
+ new_title (str): The new title of the conversation.
106
+ kwargs (Any): Additional arguments.
107
+
108
+ Returns:
109
+ Conversation: The updated conversation.
110
+ """
111
+ pass
112
+
113
+ @abstractmethod
114
+ def delete_conversation(self, user_id: str, conversation_id: str, **kwargs: Any) -> None:
115
+ """Delete a conversation by its ID.
116
+
117
+ Args:
118
+ user_id (str): The ID of the user.
119
+ conversation_id (str): The ID of the conversation.
120
+ kwargs (Any): Additional arguments.
121
+
122
+ Returns:
123
+ None
124
+ """
125
+ pass
126
+
127
+ @abstractmethod
128
+ def delete_conversations(self, user_id: str, chatbot_id: str, **kwargs: Any) -> None:
129
+ """Delete all conversations associated with a chatbot.
130
+
131
+ Args:
132
+ user_id (str): The ID of the user.
133
+ chatbot_id (str): The ID of the chatbot.
134
+ kwargs (Any): Additional arguments.
135
+
136
+ Returns:
137
+ None
138
+ """
139
+ pass
140
+
141
+ @abstractmethod
142
+ def save_message(
143
+ self,
144
+ user_id: str,
145
+ conversation_id: str,
146
+ message_list: list[Any],
147
+ attachments: dict[str, Any] | None,
148
+ **kwargs: Any,
149
+ ) -> list[Message]:
150
+ """Save a list of messages to a conversation.
151
+
152
+ Args:
153
+ user_id (str): The ID of the user.
154
+ conversation_id (str): The ID of the conversation.
155
+ message_list (list[Any]): A list of messages to save.
156
+ attachments (dict[str, Any] | None): Attachments associated with the messages.
157
+ kwargs (Any): Additional arguments.
158
+
159
+ Returns:
160
+ list[Message]: The saved messages.
161
+ """
162
+ pass
163
+
164
+ @abstractmethod
165
+ def get_message_by_id(self, message_id: str, **kwargs: Any) -> Message:
166
+ """Retrieve a specific message by its ID.
167
+
168
+ Args:
169
+ message_id (str): The ID of the message.
170
+ kwargs (Any): Additional arguments.
171
+
172
+ Returns:
173
+ Message: The message.
174
+ """
175
+ pass
176
+
177
+ @abstractmethod
178
+ def get_messages_by_ids(self, message_ids: list[str], **kwargs: Any) -> list[Message]:
179
+ """Retrieve messages by their IDs.
180
+
181
+ Args:
182
+ message_ids (list[str]): A list of message IDs.
183
+ kwargs (Any): Additional arguments.
184
+
185
+ Returns:
186
+ list[Message]: A list of messages.
187
+ """
188
+ pass
189
+
190
+ @abstractmethod
191
+ def get_messages(
192
+ self,
193
+ user_id: str,
194
+ conversation_id: str,
195
+ limit: int | None = None,
196
+ max_timestamp: datetime | None = None,
197
+ **kwargs: Any,
198
+ ) -> list[Message]:
199
+ """Retrieve messages from a conversation.
200
+
201
+ Args:
202
+ user_id (str): The ID of the user.
203
+ conversation_id (str): The ID of the conversation.
204
+ limit (int | None, optional): The maximum number of messages to retrieve. Defaults to None.
205
+ max_timestamp (datetime | None, optional): The maximum timestamp for the messages. Defaults to None.
206
+ kwargs (Any): Additional arguments.
207
+
208
+ Returns:
209
+ list[Message]: A list of messages.
210
+ """
211
+ pass
212
+
213
+ @abstractmethod
214
+ def update_message_metadata(self, message_id: str, metadata_: dict[str, Any], **kwargs: Any) -> Message:
215
+ """Update the metadata of a message.
216
+
217
+ Args:
218
+ message_id (str): The ID of the message.
219
+ metadata_ (dict[str, Any]): The metadata to update.
220
+ kwargs (Any): Additional arguments.
221
+
222
+ Returns:
223
+ Message: The updated message.
224
+ """
225
+ pass
226
+
227
+ @abstractmethod
228
+ def delete_messages(self, user_id: str, message_ids: list[str], chatbot_ids: list[str], **kwargs: Any) -> None:
229
+ """Delete messages by their IDs.
230
+
231
+ Args:
232
+ user_id (str): The ID of the user.
233
+ message_ids (list[str]): A list of message IDs to delete.
234
+ chatbot_ids (list[str]): A list of chatbot IDs associated with the messages.
235
+ kwargs (Any): Additional arguments.
236
+
237
+ Returns:
238
+ None
239
+ """
240
+ pass
241
+
242
+ @abstractmethod
243
+ def create_conversation_document(
244
+ self, conversation_id: str, status: str = DocumentStatus.PROCESSING.value, file_hash: str = "", **kwargs: Any
245
+ ) -> ConversationDocument:
246
+ """Create a new conversation document.
247
+
248
+ Args:
249
+ conversation_id (str): The ID of the conversation.
250
+ status (str, optional): The status of the document. Defaults to DocumentStatus.PROCESSING.value.
251
+ file_hash (str, optional): The hash of the file. Defaults to "".
252
+ kwargs (Any): Additional arguments.
253
+
254
+ Returns:
255
+ ConversationDocument: The created conversation document.
256
+ """
257
+ pass
258
+
259
+ @abstractmethod
260
+ def get_conversation_document(self, document_id: str, **kwargs: Any) -> ConversationDocument:
261
+ """Retrieve a conversation document by its ID.
262
+
263
+ Args:
264
+ document_id (str): The ID of the document.
265
+ kwargs (Any): Additional arguments.
266
+
267
+ Returns:
268
+ ConversationDocument: The conversation document.
269
+ """
270
+ pass
271
+
272
+ @abstractmethod
273
+ def update_conversation_document(
274
+ self,
275
+ document_id: str,
276
+ status: str,
277
+ number_of_chunks: int,
278
+ message: str | None,
279
+ object_key: str | None,
280
+ **kwargs: Any,
281
+ ) -> ConversationDocument:
282
+ """Update a conversation document.
283
+
284
+ Args:
285
+ document_id (str): The ID of the document.
286
+ status (str): The status of the document.
287
+ number_of_chunks (int): The number of chunks in the document.
288
+ message (str | None, optional): A message associated with the document. Defaults to None.
289
+ object_key (str | None, optional): The object key of the document. Defaults to None.
290
+ kwargs (Any): Additional arguments.
291
+
292
+ Returns:
293
+ ConversationDocument: The updated conversation document.
294
+ """
295
+ pass
296
+
297
+ @abstractmethod
298
+ def save_feedback(self, user_id: str, message_id: str, feedback: str, **kwargs: Any) -> None:
299
+ """Save feedback for a message.
300
+
301
+ Args:
302
+ user_id (str): The ID of the user.
303
+ message_id (str): The ID of the message.
304
+ feedback (str): The feedback content.
305
+ kwargs (Any): Additional arguments.
306
+
307
+ Returns:
308
+ None
309
+ """
310
+ pass
311
+
312
+ @abstractmethod
313
+ def get_deanonymized_message(
314
+ self,
315
+ user_id: str,
316
+ conversation_id: str,
317
+ message_id: str,
318
+ is_anonymized: bool,
319
+ mappings: list[AnonymizerMapping],
320
+ **kwargs: Any,
321
+ ) -> Message:
322
+ """Retrieve a deanonymized message.
323
+
324
+ Args:
325
+ user_id (str): The ID of the user.
326
+ conversation_id (str): The ID of the conversation.
327
+ message_id (str): The ID of the message.
328
+ is_anonymized (bool): Whether the message is anonymized.
329
+ mappings (list[AnonymizerMapping]): A list of anonymizer mappings.
330
+ kwargs (Any): Additional arguments.
331
+
332
+ Returns:
333
+ Message: The deanonymized message.
334
+ """
335
+ pass
336
+
337
+ @abstractmethod
338
+ def get_deanonymized_messages(
339
+ self,
340
+ messages: list[Message],
341
+ is_anonymized: bool,
342
+ mappings: list[AnonymizerMapping] | None = None,
343
+ **kwargs: Any,
344
+ ) -> list[Message]:
345
+ """Retrieve a list of deanonymized messages.
346
+
347
+ Args:
348
+ messages (list[Message]): A list of messages.
349
+ is_anonymized (bool): Whether the messages are anonymized.
350
+ mappings (list[AnonymizerMapping] | None, optional): A list of anonymizer mappings. Defaults to None.
351
+ kwargs (Any): Additional arguments.
352
+
353
+ Returns:
354
+ list[Message]: A list of deanonymized messages.
355
+ """
356
+ pass
@@ -0,0 +1,21 @@
1
+ """Tool plugin system for GLLM Agents.
2
+
3
+ This module provides a plugin system for tools, allowing dynamic marking and preparation of tools
4
+ similar to VSCode's extension model. Tools can be decorated with metadata while remaining independent
5
+ from the core registration mechanism.
6
+
7
+ Authors:
8
+ Raymond Christopher (raymond.christopher@gdplabs.id)
9
+ """
10
+
11
+ from glchat_plugin.tools.decorators import (
12
+ get_plugin_metadata,
13
+ is_tool_plugin,
14
+ tool_plugin,
15
+ )
16
+
17
+ __all__ = [
18
+ "tool_plugin",
19
+ "is_tool_plugin",
20
+ "get_plugin_metadata",
21
+ ]