gllm-plugin 0.0.5.dev1__cp311-cp311-macosx_14_0_arm64.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.
File without changes
File without changes
@@ -0,0 +1,9 @@
1
+ from pydantic import BaseModel
2
+ from typing import TypeVar
3
+
4
+ Chatbot = TypeVar('Chatbot')
5
+
6
+ class AppConfig(BaseModel):
7
+ """Application configuration model."""
8
+ chatbots: dict[str, Chatbot]
9
+ user_chatbots: dict[str, list[str]]
@@ -0,0 +1,15 @@
1
+ from enum import StrEnum
2
+
3
+ class SearchType(StrEnum):
4
+ """The type of search to perform.
5
+
6
+ Values:
7
+ NORMAL: Get answer from chatbot knowledge.
8
+ SMART: Get more relevant information from your stored documents and knowledge base.
9
+ Knowledge Search is an AI with specialized knowledge. No agents are available in this mode.
10
+ WEB: Get more relevant information from the web.
11
+ Web Search uses real-time data. Agent selection isn't available in this mode.
12
+ """
13
+ NORMAL = 'normal'
14
+ SMART = 'smart'
15
+ WEB = 'web'
File without changes
@@ -0,0 +1,23 @@
1
+ from gllm_plugin.config.constant import SearchType as SearchType
2
+ from pydantic import BaseModel
3
+ from typing import Any
4
+
5
+ class BasePipelinePresetConfig(BaseModel):
6
+ """A Pydantic model representing the base preset configuration of all pipelines.
7
+
8
+ Attributes:
9
+ pipeline_preset_id (str): The pipeline preset id.
10
+ supported_models (dict[str, Any]): The supported models.
11
+ supported_agents (list[str]): The supported agents.
12
+ support_pii_anonymization (bool): Whether the pipeline supports pii anonymization.
13
+ support_multimodal (bool): Whether the pipeline supports multimodal.
14
+ use_docproc (bool): Whether to use the document processor.
15
+ search_types (list[SearchType]): The supported search types.
16
+ """
17
+ pipeline_preset_id: str
18
+ supported_models: dict[str, Any]
19
+ supported_agents: list[str]
20
+ support_pii_anonymization: bool
21
+ support_multimodal: bool
22
+ use_docproc: bool
23
+ search_types: list[SearchType]
@@ -0,0 +1,157 @@
1
+ from _typeshed import Incomplete
2
+ from bosa_core import Plugin as Plugin
3
+ from bosa_core.plugin.handler import PluginHandler
4
+ from gllm_inference.catalog import LMRequestProcessorCatalog as LMRequestProcessorCatalog, PromptBuilderCatalog as PromptBuilderCatalog
5
+ from gllm_pipeline.pipeline.pipeline import Pipeline as Pipeline
6
+ from gllm_plugin.config.app_config import AppConfig as AppConfig
7
+ from gllm_plugin.storage.base_chat_history_storage import BaseChatHistoryStorage as BaseChatHistoryStorage
8
+ from gllm_plugin.supported_models import ModelName as ModelName
9
+ from pydantic import BaseModel
10
+ from typing import Any
11
+
12
+ class ChatbotConfig(BaseModel):
13
+ """Chatbot configuration class containing pipeline configs and metadata.
14
+
15
+ Attributes:
16
+ pipeline_type (str): Type of pipeline to use.
17
+ pipeline_config (dict[str, Any]): Pipeline configuration dictionary.
18
+ prompt_builder_catalogs (dict[str, PromptBuilderCatalog] | None): Mapping of prompt builder catalogs.
19
+ lmrp_catalogs (dict[str, LMRequestProcessorCatalog] | None): Mapping of LM request processor catalogs.
20
+ """
21
+ pipeline_type: str
22
+ pipeline_config: dict[str, Any]
23
+ prompt_builder_catalogs: dict[str, PromptBuilderCatalog] | None
24
+ lmrp_catalogs: dict[str, LMRequestProcessorCatalog] | None
25
+ model_config: Incomplete
26
+
27
+ class PipelinePresetConfig(BaseModel):
28
+ """Pipeline preset configuration class.
29
+
30
+ Attributes:
31
+ preset_id (str): Unique identifier for the pipeline preset.
32
+ supported_models (list[str]): List of model names supported by this preset.
33
+ """
34
+ preset_id: str
35
+ supported_models: list[str]
36
+
37
+ class ChatbotPresetMapping(BaseModel):
38
+ """Chatbot preset mapping.
39
+
40
+ Attributes:
41
+ pipeline_type (str): Type of pipeline.
42
+ chatbot_preset_map (dict[str, PipelinePresetConfig]): Mapping of chatbot IDs to their pipeline preset configurations.
43
+ """
44
+ pipeline_type: str
45
+ chatbot_preset_map: dict[str, PipelinePresetConfig]
46
+
47
+ logger: Incomplete
48
+
49
+ class PipelineHandler(PluginHandler):
50
+ """Handler for pipeline builder plugins.
51
+
52
+ This handler manages pipeline builder plugins and provides caching for built pipelines.
53
+
54
+ Attributes:
55
+ app_config (AppConfig): Application configuration.
56
+ _activated_configs (dict[str, ChatbotPresetMapping]): Collection of chatbot preset mapping by pipeline types.
57
+ _chatbot_configs (dict[str, ChatbotConfig]): Mapping of chatbot IDs to their configurations.
58
+ _builders (dict[str, Plugin]): Mapping of chatbot IDs to their pipeline builder plugins.
59
+ _pipeline_cache (dict[tuple[str, str], Pipeline]): Cache mapping (chatbot_id, model_name) to Pipeline instances.
60
+ """
61
+ app_config: AppConfig
62
+ chat_history_storage: Incomplete
63
+ def __init__(self, app_config: AppConfig, chat_history_storage: BaseChatHistoryStorage) -> None:
64
+ """Initialize the pipeline handler.
65
+
66
+ Args:
67
+ app_config (AppConfig): Application configuration.
68
+ chat_history_storage (BaseChatHistoryStorage): Chat history storage.
69
+ """
70
+ @classmethod
71
+ def create_injections(cls, instance: PipelineHandler) -> dict[type[Any], Any]:
72
+ """Create injection mappings for pipeline builder plugins.
73
+
74
+ Args:
75
+ instance (PipelineHandler): The handler instance providing injections.
76
+
77
+ Returns:
78
+ dict[Type[Any], Any]: Dictionary mapping service types to their instances.
79
+ """
80
+ @classmethod
81
+ def initialize_plugin(cls, instance: PipelineHandler, plugin: Plugin) -> None:
82
+ """Initialize plugin-specific resources.
83
+
84
+ This method is called after plugin creation and service injection.
85
+ For each pipeline builder plugin, we build pipelines for all supported models and cache them.
86
+
87
+ Args:
88
+ instance (PipelineHandler): The handler instance.
89
+ plugin (Plugin): The pipeline builder plugin instance.
90
+ """
91
+ def get_pipeline_builder(self, chatbot_id: str) -> Plugin:
92
+ """Get a pipeline builder instance for the given chatbot.
93
+
94
+ Args:
95
+ chatbot_id (str): The chatbot ID.
96
+
97
+ Returns:
98
+ Plugin: The pipeline builder instance.
99
+
100
+ Raises:
101
+ ValueError: If the chatbot ID is invalid or the model name is not supported.
102
+ """
103
+ def get_pipeline(self, chatbot_id: str, model_name: ModelName) -> Pipeline:
104
+ """Get a pipeline instance for the given chatbot and model name.
105
+
106
+ Args:
107
+ chatbot_id (str): The chatbot ID.
108
+ model_name (ModelName): The model to use for inference.
109
+
110
+ Returns:
111
+ Pipeline: The pipeline instance.
112
+
113
+ Raises:
114
+ ValueError: If the chatbot ID is invalid.
115
+ """
116
+ def get_pipeline_config(self, chatbot_id: str) -> dict[str, Any]:
117
+ """Get the pipeline configuration by chatbot ID.
118
+
119
+ Args:
120
+ chatbot_id (str): The chatbot ID.
121
+
122
+ Returns:
123
+ dict[str, Any]: The pipeline configuration.
124
+
125
+ Raises:
126
+ ValueError: If the chatbot or pipeline is not found.
127
+ """
128
+ def get_pipeline_type(self, chatbot_id: str) -> str:
129
+ """Get the pipeline type for the given chatbot.
130
+
131
+ Args:
132
+ chatbot_id (str): The chatbot ID.
133
+ """
134
+ def get_use_docproc(self, chatbot_id: str) -> bool:
135
+ """Get whether DocProc should be used for this chatbot.
136
+
137
+ Args:
138
+ chatbot_id (str): The chatbot ID.
139
+
140
+ Returns:
141
+ bool: Whether DocProc should be used.
142
+
143
+ Raises:
144
+ ValueError: If the chatbot or pipeline is not found.
145
+ """
146
+ def get_max_file_size(self, chatbot_id: str) -> int | None:
147
+ """Get maximum file size for the given chatbot.
148
+
149
+ Args:
150
+ chatbot_id (str): The chatbot ID.
151
+
152
+ Returns:
153
+ int | None: The maximum file size if provided.
154
+
155
+ Raises:
156
+ ValueError: If the chatbot or pipeline is not found.
157
+ """
@@ -0,0 +1,78 @@
1
+ import abc
2
+ from abc import ABC, abstractmethod
3
+ from bosa_core.plugin.plugin import Plugin
4
+ from gllm_inference.catalog.catalog import BaseCatalog as BaseCatalog
5
+ from gllm_pipeline.pipeline.pipeline import Pipeline as Pipeline
6
+ from gllm_plugin.pipeline.pipeline_handler import PipelineHandler as PipelineHandler
7
+ from typing import Any, Generic, TypeVar
8
+
9
+ PipelineState = TypeVar('PipelineState')
10
+ PipelinePresetConfig = TypeVar('PipelinePresetConfig', bound='BasePipelinePresetConfig')
11
+ PipelineRuntimeConfig = TypeVar('PipelineRuntimeConfig', bound='BaseModel')
12
+
13
+ class PipelineBuilderPlugin(Plugin, ABC, Generic[PipelineState, PipelinePresetConfig], metaclass=abc.ABCMeta):
14
+ """Base class for pipeline builder plugins.
15
+
16
+ This class combines the Plugin architecture with the Pipeline Builder functionality.
17
+
18
+ Attributes:
19
+ name (str): The name of the plugin.
20
+ description (str): The description of the plugin.
21
+ version (str): The version of the plugin.
22
+ catalog (BaseCatalog): The catalog instance.
23
+ additional_config_class (Type[PipelineRuntimeConfig] | None): The additional runtime configuration class.
24
+ preset_config_class (Type[PipelinePresetConfig] | None): The preset configuration class.
25
+ """
26
+ name: str
27
+ description: str
28
+ version: str
29
+ catalog: BaseCatalog[Any]
30
+ additional_config_class: type[PipelineRuntimeConfig] | None
31
+ preset_config_class: type[PipelinePresetConfig] | None
32
+ @classmethod
33
+ def get_preset_config_class(cls) -> type[PipelinePresetConfig]:
34
+ """Get the preset_config_class.
35
+
36
+ Returns:
37
+ Type[PipelinePresetConfig]: The pipeline preset config class.
38
+
39
+ Raises:
40
+ NotImplementedError: If the preset_config_class is not defined.
41
+ """
42
+ @abstractmethod
43
+ def build_initial_state(self, request_config: dict[str, Any], pipeline_config: dict[str, Any], **kwargs: Any) -> PipelineState:
44
+ """Build the initial pipeline state.
45
+
46
+ Args:
47
+ request_config (dict[str, Any]): Request configuration.
48
+ pipeline_config (dict[str, Any]): Pipeline configuration.
49
+ kwargs (Any): Additional state arguments.
50
+
51
+ Returns:
52
+ PipelineState: Initial pipeline state.
53
+ """
54
+ @abstractmethod
55
+ def build(self, pipeline_config: dict[str, Any]) -> Pipeline:
56
+ """Build a pipeline instance.
57
+
58
+ Args:
59
+ pipeline_config (dict[str, Any]): Pipeline configuration including model name and other settings.
60
+
61
+ Returns:
62
+ Pipeline: Built pipeline instance.
63
+ """
64
+ def build_additional_runtime_config(self, pipeline_config: dict[str, Any]) -> dict[str, Any]:
65
+ """Build additional runtime configuration.
66
+
67
+ Args:
68
+ pipeline_config (dict[str, Any]): Pipeline configuration.
69
+
70
+ Returns:
71
+ dict[str, Any]: Additional runtime configuration.
72
+ """
73
+ def get_config(self) -> dict[str, Any]:
74
+ """Get the pipeline configuration.
75
+
76
+ Returns:
77
+ dict[str, Any]: Pipeline configuration.
78
+ """
File without changes
@@ -0,0 +1,41 @@
1
+ import abc
2
+ from abc import ABC, abstractmethod
3
+ from typing import TypeVar
4
+
5
+ AnonymizerMapping = TypeVar('AnonymizerMapping')
6
+ MappingDataType = TypeVar('MappingDataType')
7
+
8
+ class BaseAnonymizerStorage(ABC, metaclass=abc.ABCMeta):
9
+ """Interface for anonymizer storage that defines methods for managing anonymizer mappings."""
10
+ @abstractmethod
11
+ def get_mappings_by_conversation_id(self, conversation_id: str) -> list[AnonymizerMapping]:
12
+ """Retrieve anonymizer mappings by conversation ID.
13
+
14
+ Args:
15
+ conversation_id (str): The ID of the conversation.
16
+
17
+ Returns:
18
+ list[AnonymizerMapping]: A list of anonymizer mappings associated with the conversation ID.
19
+ """
20
+ @abstractmethod
21
+ def create_mapping(self, conversation_id: str, pii_type: str, anonymized_value: str, pii_value: str) -> AnonymizerMapping:
22
+ """Create a new anonymizer mapping.
23
+
24
+ Args:
25
+ conversation_id (str): The ID of the conversation.
26
+ pii_type (str): The type of personally identifiable information (PII).
27
+ anonymized_value (str): The anonymized value of the PII.
28
+ pii_value (str): The original PII value.
29
+
30
+ Returns:
31
+ AnonymizerMapping: The created anonymizer mapping.
32
+ """
33
+ @abstractmethod
34
+ def update_mapping(self, conversation_id: str, is_anonymized: bool, mapping_data_type: MappingDataType) -> None:
35
+ """Update the mappings for a specific conversation with new anonymizer mappings.
36
+
37
+ Args:
38
+ conversation_id (str): The unique identifier for the conversation.
39
+ is_anonymized (bool): The flag to determine if the message is anonymized.
40
+ mapping_data_type (MappingDataType): A dictionary of new anonymizer mappings to update for deanonymization.
41
+ """
@@ -0,0 +1,287 @@
1
+ import abc
2
+ from abc import ABC, abstractmethod
3
+ from datetime import datetime
4
+ from enum import StrEnum
5
+ from gllm_plugin.storage.base_anonymizer_storage import AnonymizerMapping as AnonymizerMapping
6
+ from typing import Any
7
+ from typing_extensions import TypeVar
8
+
9
+ Conversation = TypeVar('Conversation')
10
+ Message = TypeVar('Message')
11
+ ConversationDocument = TypeVar('ConversationDocument')
12
+
13
+ class MessageRole(StrEnum):
14
+ """Enum for Message Type."""
15
+ USER = 'USER'
16
+ AI = 'AI'
17
+
18
+ class DocumentStatus(StrEnum):
19
+ """Enum for ConversationDocument Status."""
20
+ PROCESSING = 'processing'
21
+ DONE = 'done'
22
+ FAILED = 'failed'
23
+
24
+ class BaseChatHistoryStorage(ABC, metaclass=abc.ABCMeta):
25
+ """Interface for chat history storage that defines methods for managing chat conversations and messages."""
26
+ @abstractmethod
27
+ def create_conversation(self, user_id: str, conversation_title: str, chatbot_id: str, **kwargs: Any) -> Conversation:
28
+ """Create a new conversation.
29
+
30
+ Args:
31
+ user_id (str): The ID of the user.
32
+ conversation_title (str): The title of the conversation.
33
+ chatbot_id (str): The ID of the chatbot.
34
+ kwargs (Any): Additional arguments.
35
+
36
+ Returns:
37
+ Conversation: The created conversation.
38
+ """
39
+ @abstractmethod
40
+ def get_conversation(self, user_id: str, conversation_id: str, **kwargs: Any) -> Conversation | None:
41
+ """Retrieve a specific conversation by its ID.
42
+
43
+ Args:
44
+ user_id (str): The ID of the user.
45
+ conversation_id (str): The ID of the conversation.
46
+ kwargs (Any): Additional arguments.
47
+
48
+ Returns:
49
+ Conversation | None: The conversation if found, otherwise None.
50
+ """
51
+ @abstractmethod
52
+ def get_conversations(self, user_id: str, query: str = '', chatbot_ids: list[str] | None = None, cursor: str | None = None, limit: int | None = None, **kwargs: Any) -> list[Conversation]:
53
+ '''Retrieve a list of conversations for a user.
54
+
55
+ Args:
56
+ user_id (str): The ID of the user.
57
+ query (str, optional): A search query to filter conversations. Defaults to "".
58
+ chatbot_ids (list[str] | None, optional): A list of chatbot IDs to filter conversations. Defaults to None.
59
+ cursor (str | None, optional): A cursor for pagination. Defaults to None.
60
+ limit (int | None, optional): The maximum number of conversations to retrieve. Defaults to None.
61
+ kwargs (Any): Additional arguments.
62
+
63
+ Returns:
64
+ list[Conversation]: A list of conversations.
65
+ '''
66
+ @abstractmethod
67
+ def rename_conversation(self, user_id: str, conversation_id: str, new_title: str, **kwargs: Any) -> Conversation:
68
+ """Rename an existing conversation.
69
+
70
+ Args:
71
+ user_id (str): The ID of the user.
72
+ conversation_id (str): The ID of the conversation.
73
+ new_title (str): The new title of the conversation.
74
+ kwargs (Any): Additional arguments.
75
+
76
+ Returns:
77
+ Conversation: The updated conversation.
78
+ """
79
+ @abstractmethod
80
+ def delete_conversation(self, user_id: str, conversation_id: str, **kwargs: Any) -> None:
81
+ """Delete a conversation by its ID.
82
+
83
+ Args:
84
+ user_id (str): The ID of the user.
85
+ conversation_id (str): The ID of the conversation.
86
+ kwargs (Any): Additional arguments.
87
+
88
+ Returns:
89
+ None
90
+ """
91
+ @abstractmethod
92
+ def delete_conversations(self, user_id: str, chatbot_id: str, **kwargs: Any) -> None:
93
+ """Delete all conversations associated with a chatbot.
94
+
95
+ Args:
96
+ user_id (str): The ID of the user.
97
+ chatbot_id (str): The ID of the chatbot.
98
+ kwargs (Any): Additional arguments.
99
+
100
+ Returns:
101
+ None
102
+ """
103
+ @abstractmethod
104
+ def add_user_message(self, message: str, user_id: str, conversation_id: str, parent_id: str | None = None, source: str | None = None, **kwargs: Any) -> Message:
105
+ """Add a user message to a conversation.
106
+
107
+ Args:
108
+ message (str): The message content.
109
+ user_id (str): The ID of the user.
110
+ conversation_id (str): The ID of the conversation.
111
+ parent_id (str | None, optional): The ID of the parent message. Defaults to None.
112
+ source (str | None, optional): The source of the message. Defaults to None.
113
+ kwargs (Any): Additional arguments.
114
+
115
+ Returns:
116
+ Message: The added message.
117
+ """
118
+ @abstractmethod
119
+ def add_ai_message(self, message: str, user_id: str, conversation_id: str, parent_id: str | None = None, source: str | None = None, **kwargs: Any) -> Message:
120
+ """Add an AI message to a conversation.
121
+
122
+ Args:
123
+ message (str): The message content.
124
+ user_id (str): The ID of the user.
125
+ conversation_id (str): The ID of the conversation.
126
+ parent_id (str | None, optional): The ID of the parent message. Defaults to None.
127
+ source (str | None, optional): The source of the message. Defaults to None.
128
+ kwargs (Any): Additional arguments.
129
+
130
+ Returns:
131
+ Message: The added message.
132
+ """
133
+ @abstractmethod
134
+ def save_message(self, user_id: str, conversation_id: str, message_list: list[Any], attachments: dict[str, Any] | None, **kwargs: Any) -> list[Message]:
135
+ """Save a list of messages to a conversation.
136
+
137
+ Args:
138
+ user_id (str): The ID of the user.
139
+ conversation_id (str): The ID of the conversation.
140
+ message_list (list[Any]): A list of messages to save.
141
+ attachments (dict[str, Any] | None): Attachments associated with the messages.
142
+ kwargs (Any): Additional arguments.
143
+
144
+ Returns:
145
+ list[Message]: The saved messages.
146
+ """
147
+ @abstractmethod
148
+ def get_message_by_id(self, message_id: str, **kwargs: Any) -> Message:
149
+ """Retrieve a specific message by its ID.
150
+
151
+ Args:
152
+ message_id (str): The ID of the message.
153
+ kwargs (Any): Additional arguments.
154
+
155
+ Returns:
156
+ Message: The message.
157
+ """
158
+ @abstractmethod
159
+ def get_messages_by_ids(self, message_ids: list[str], **kwargs: Any) -> list[Message]:
160
+ """Retrieve messages by their IDs.
161
+
162
+ Args:
163
+ message_ids (list[str]): A list of message IDs.
164
+ kwargs (Any): Additional arguments.
165
+
166
+ Returns:
167
+ list[Message]: A list of messages.
168
+ """
169
+ @abstractmethod
170
+ def get_messages(self, user_id: str, conversation_id: str, limit: int | None = None, max_timestamp: datetime | None = None, **kwargs: Any) -> list[Message]:
171
+ """Retrieve messages from a conversation.
172
+
173
+ Args:
174
+ user_id (str): The ID of the user.
175
+ conversation_id (str): The ID of the conversation.
176
+ limit (int | None, optional): The maximum number of messages to retrieve. Defaults to None.
177
+ max_timestamp (datetime | None, optional): The maximum timestamp for the messages. Defaults to None.
178
+ kwargs (Any): Additional arguments.
179
+
180
+ Returns:
181
+ list[Message]: A list of messages.
182
+ """
183
+ @abstractmethod
184
+ def update_message_metadata(self, message_id: str, metadata_: dict[str, Any], **kwargs: Any) -> Message:
185
+ """Update the metadata of a message.
186
+
187
+ Args:
188
+ message_id (str): The ID of the message.
189
+ metadata_ (dict[str, Any]): The metadata to update.
190
+ kwargs (Any): Additional arguments.
191
+
192
+ Returns:
193
+ Message: The updated message.
194
+ """
195
+ @abstractmethod
196
+ def delete_messages(self, user_id: str, message_ids: list[str], chatbot_ids: list[str], **kwargs: Any) -> None:
197
+ """Delete messages by their IDs.
198
+
199
+ Args:
200
+ user_id (str): The ID of the user.
201
+ message_ids (list[str]): A list of message IDs to delete.
202
+ chatbot_ids (list[str]): A list of chatbot IDs associated with the messages.
203
+ kwargs (Any): Additional arguments.
204
+
205
+ Returns:
206
+ None
207
+ """
208
+ @abstractmethod
209
+ def create_conversation_document(self, conversation_id: str, status: str = ..., file_hash: str = '', **kwargs: Any) -> ConversationDocument:
210
+ '''Create a new conversation document.
211
+
212
+ Args:
213
+ conversation_id (str): The ID of the conversation.
214
+ status (str, optional): The status of the document. Defaults to DocumentStatus.PROCESSING.value.
215
+ file_hash (str, optional): The hash of the file. Defaults to "".
216
+ kwargs (Any): Additional arguments.
217
+
218
+ Returns:
219
+ ConversationDocument: The created conversation document.
220
+ '''
221
+ @abstractmethod
222
+ def get_conversation_document(self, document_id: str, **kwargs: Any) -> ConversationDocument:
223
+ """Retrieve a conversation document by its ID.
224
+
225
+ Args:
226
+ document_id (str): The ID of the document.
227
+ kwargs (Any): Additional arguments.
228
+
229
+ Returns:
230
+ ConversationDocument: The conversation document.
231
+ """
232
+ @abstractmethod
233
+ def update_conversation_document(self, document_id: str, status: str, number_of_chunks: int, message: str | None, object_key: str | None, **kwargs: Any) -> ConversationDocument:
234
+ """Update a conversation document.
235
+
236
+ Args:
237
+ document_id (str): The ID of the document.
238
+ status (str): The status of the document.
239
+ number_of_chunks (int): The number of chunks in the document.
240
+ message (str | None, optional): A message associated with the document. Defaults to None.
241
+ object_key (str | None, optional): The object key of the document. Defaults to None.
242
+ kwargs (Any): Additional arguments.
243
+
244
+ Returns:
245
+ ConversationDocument: The updated conversation document.
246
+ """
247
+ @abstractmethod
248
+ def save_feedback(self, user_id: str, message_id: str, feedback: str, **kwargs: Any) -> None:
249
+ """Save feedback for a message.
250
+
251
+ Args:
252
+ user_id (str): The ID of the user.
253
+ message_id (str): The ID of the message.
254
+ feedback (str): The feedback content.
255
+ kwargs (Any): Additional arguments.
256
+
257
+ Returns:
258
+ None
259
+ """
260
+ @abstractmethod
261
+ def get_deanonymized_message(self, user_id: str, conversation_id: str, message_id: str, is_anonymized: bool, mappings: list[AnonymizerMapping], **kwargs: Any) -> Message:
262
+ """Retrieve a deanonymized message.
263
+
264
+ Args:
265
+ user_id (str): The ID of the user.
266
+ conversation_id (str): The ID of the conversation.
267
+ message_id (str): The ID of the message.
268
+ is_anonymized (bool): Whether the message is anonymized.
269
+ mappings (list[AnonymizerMapping]): A list of anonymizer mappings.
270
+ kwargs (Any): Additional arguments.
271
+
272
+ Returns:
273
+ Message: The deanonymized message.
274
+ """
275
+ @abstractmethod
276
+ def get_deanonymized_messages(self, messages: list[Message], is_anonymized: bool, mappings: list[AnonymizerMapping] | None = None, **kwargs: Any) -> list[Message]:
277
+ """Retrieve a list of deanonymized messages.
278
+
279
+ Args:
280
+ messages (list[Message]): A list of messages.
281
+ is_anonymized (bool): Whether the messages are anonymized.
282
+ mappings (list[AnonymizerMapping] | None, optional): A list of anonymizer mappings. Defaults to None.
283
+ kwargs (Any): Additional arguments.
284
+
285
+ Returns:
286
+ list[Message]: A list of deanonymized messages.
287
+ """
@@ -0,0 +1,172 @@
1
+ from _typeshed import Incomplete
2
+ from enum import StrEnum
3
+ from pydantic import BaseModel, BeforeValidator as BeforeValidator, HttpUrl
4
+ from typing import Annotated
5
+
6
+ class Provider(StrEnum):
7
+ """Supported model providers."""
8
+ ANTHROPIC = 'anthropic'
9
+ DEEPSEEK = 'deepseek'
10
+ GOOGLE = 'google'
11
+ OPENAI = 'openai'
12
+ TGI = 'tgi'
13
+ TEI = 'tei'
14
+ VLLM = 'vllm'
15
+ GROQ = 'groq'
16
+ TOGETHER_AI = 'together-ai'
17
+ DEEPINFRA = 'deepinfra'
18
+ ROUTABLE = 'routable'
19
+
20
+ class OpenAIModel(StrEnum):
21
+ """Supported OpenAI models."""
22
+ GPT_4O = 'gpt-4o'
23
+ GPT_4O_MINI = 'gpt-4o-mini'
24
+ GPT_4_5_PREVIEW = 'gpt-4.5-preview'
25
+ O1 = 'o1'
26
+ O1_MINI = 'o1-mini'
27
+ O1_PREVIEW = 'o1-preview'
28
+ O3 = 'o3'
29
+ O3_MINI = 'o3-mini'
30
+ TEXT_EMBEDDING_3_SMALL = 'text-embedding-3-small'
31
+ TEXT_EMBEDDING_3_LARGE = 'text-embedding-3-large'
32
+ TEXT_EMBEDDING_ADA_002 = 'text-embedding-ada-002'
33
+
34
+ class AnthropicModel(StrEnum):
35
+ """Supported Anthropic models."""
36
+ CLAUDE_3_7_SONNET = 'claude-3-7-sonnet'
37
+ CLAUDE_3_5_SONNET = 'claude-3-5-sonnet'
38
+ CLAUDE_3_5_HAIKU = 'claude-3-5-haiku'
39
+ CLAUDE_3_OPUS = 'claude-3-opus'
40
+
41
+ class GoogleModel(StrEnum):
42
+ """Supported Google models."""
43
+ GEMINI_1_5_FLASH = 'gemini-1.5-flash'
44
+ GEMINI_1_5_FLASH_8B = 'gemini-1.5-flash-8b'
45
+ GEMINI_1_5_PRO = 'gemini-1.5-pro'
46
+ GEMINI_2_0_FLASH = 'gemini-2.0-flash'
47
+ TEXT_EMBEDDING_GECKO_001 = 'textembedding-gecko@001'
48
+ TEXT_EMBEDDING_GECKO_003 = 'textembedding-gecko@003'
49
+ TEXT_EMBEDDING_004 = 'text-embedding-004'
50
+ TEXT_EMBEDDING_005 = 'text-embedding-005'
51
+
52
+ class DeepSeekModel(StrEnum):
53
+ """Supported DeepSeek models."""
54
+ DEEPSEEK_CHAT = 'deepseek-chat'
55
+ DEEPSEEK_REASONER = 'deepseek-reasoner'
56
+
57
+ class GroqModel(StrEnum):
58
+ """Supported Groq models."""
59
+ DEEPSEEK_R1_DISTILL_QWEN_32B = 'deepseek-r1-distill-qwen-32b'
60
+ DEEPSEEK_R1_DISTILL_LLAMA_70B = 'deepseek-r1-distill-llama-70b'
61
+ LLAMA_3_2_1B_PREVIEW = 'llama-3.2-1b-preview'
62
+
63
+ class TogetherAIModel(StrEnum):
64
+ """Supported Together.AI models."""
65
+ DEEPSEEK_V3 = 'deepseek-ai/DeepSeek-V3'
66
+
67
+ class DeepInfraModel(StrEnum):
68
+ """Supported DeepInfra models."""
69
+ QWEN_2_5_72B_INSTRUCT = 'Qwen/Qwen2.5-72B-Instruct'
70
+ DEEPSEEK_R1_DISTILL_QWEN_32B = 'deepseek-ai/DeepSeek-R1-Distill-Qwen-32B'
71
+ DEEPSEEK_R1 = 'deepseek-ai/DeepSeek-R1'
72
+ DEEPSEEK_V3 = 'deepseek-ai/DeepSeek-V3'
73
+
74
+ class RoutableModel(StrEnum):
75
+ """Supported routable model presets.
76
+
77
+ These are presets that map a specific model name to a routable invoker.
78
+ The actual invoker will be determined by the router.
79
+
80
+ Currently supports:
81
+ - '__default__' - Strong model: gpt-4o. Weak model: gpt-4o-mini.
82
+ - 'gpt' - Strong model: o3-mini. Weak model: gpt-4o.
83
+ - 'deepseek' - Strong model: DeepSeek-R1-Distill-Qwen-32B. Weak model: DeepSeek-V3.
84
+ """
85
+ DEFAULT = '__default__'
86
+ GPT = 'gpt'
87
+ DEEPSEEK = 'deepseek'
88
+
89
+ MODEL_MAP: Incomplete
90
+ DEFAULT_VERSION_MAP: Incomplete
91
+ UNIMODAL_PROVIDERS: Incomplete
92
+
93
+ def validate_model_name(model_name: str, provider: Provider) -> str:
94
+ """A Pydantic validator that validates the model name is valid for the given provider.
95
+
96
+ Args:
97
+ model_name (str): The model name to validate.
98
+ provider (Provider): The provider to validate the model name against.
99
+
100
+ Returns:
101
+ str: The validated model name.
102
+
103
+ Raises:
104
+ ValueError: If the model name is invalid for the provider.
105
+ """
106
+
107
+ class ModelName(BaseModel):
108
+ """A model name in a standardized format.
109
+
110
+ - For cloud providers: 'provider/model-name[-version]'
111
+ - For TGI: 'tgi/[base64-encoded-url]'
112
+ - For VLLM: 'vllm/[model-name]@[base64-encoded-url]'
113
+
114
+ Args:
115
+ provider (Provider): The provider of the model.
116
+ name (str): The name of the model.
117
+ version (str | None, optional): The version of the model. Defaults to None.
118
+ url (HttpUrl | None, optional): The URL for self-hosted models (e.g. TGI, VLLM). Defaults to None.
119
+
120
+ Attributes:
121
+ provider (Provider): The provider of the model.
122
+ name (str): The name of the model.
123
+ version (str | None): The version of the model.
124
+ url (HttpUrl | None): The URL for self-hosted models (e.g. TGI, VLLM).
125
+
126
+ Raises:
127
+ ValueError: If the model name is invalid for the provider.
128
+ """
129
+ model_config: Incomplete
130
+ provider: Provider
131
+ name: Annotated[str, None]
132
+ version: Annotated[str | None, None]
133
+ url: HttpUrl | None
134
+ @classmethod
135
+ def from_string(cls, provider_model_string: str) -> ModelName:
136
+ """Parse a provider/model string into a ModelName.
137
+
138
+ Format varies by provider:
139
+ - Cloud providers: 'provider/model-name[-version]'
140
+ - TGI: 'tgi/[base64-encoded-url]'
141
+ - TEI: 'tei/[base64-encoded-url]'
142
+ - VLLM: 'vllm/[model-name]@[base64-encoded-url]'
143
+
144
+ Args:
145
+ provider_model_string (str): The provider/model string.
146
+
147
+ Returns:
148
+ ModelName: The parsed model name.
149
+
150
+ Raises:
151
+ ValueError: If the string format is invalid or the provider is not supported.
152
+ """
153
+ def to_string(self) -> str:
154
+ """Return the standard format as a string.
155
+
156
+ Returns:
157
+ str: The formatted string representation.
158
+ """
159
+ def get_full_name(self) -> str:
160
+ """Return the complete model identifier.
161
+
162
+ For cloud providers: name[-version]
163
+ For TGI: base64-encoded-url
164
+ For TEI: base64-encoded-url
165
+ For VLLM: model-name@base64-encoded-url
166
+
167
+ Returns:
168
+ str: The complete model identifier.
169
+
170
+ Raises:
171
+ ValueError: If URL is required but not provided, or if URL is invalid.
172
+ """
@@ -0,0 +1,3 @@
1
+ from gllm_plugin.tools.decorators import get_plugin_metadata as get_plugin_metadata, is_tool_plugin as is_tool_plugin, tool_plugin as tool_plugin
2
+
3
+ __all__ = ['tool_plugin', 'is_tool_plugin', 'get_plugin_metadata']
@@ -0,0 +1,53 @@
1
+ from _typeshed import Incomplete
2
+ from langchain_core.tools import BaseTool
3
+ from typing import Any, Callable
4
+
5
+ logger: Incomplete
6
+
7
+ def tool_plugin(version: str = '1.0.0') -> Callable[[type[BaseTool]], type[BaseTool]]:
8
+ '''Decorator to mark a BaseTool class as a tool plugin.
9
+
10
+ This decorator adds metadata to the tool class that will be used by the
11
+ plugin system when the tool is loaded. It doesn\'t directly register
12
+ the tool with any system, allowing for use in external repositories.
13
+ The actual tool name and description are intended to be retrieved
14
+ from the tool instance at runtime.
15
+
16
+ Args:
17
+ version (str): Version of the plugin. Defaults to "1.0.0".
18
+
19
+ Returns:
20
+ Callable[[Type[BaseTool]], Type[BaseTool]]: A decorator function that wraps the tool class.
21
+
22
+ Example:
23
+ ```python
24
+ @tool_plugin(version="1.0.0")
25
+ class MyAwesomeTool(BaseTool):
26
+ name = "my_awesome_tool"
27
+ description = "Does something awesome"
28
+
29
+ def _run(self, **kwargs):
30
+ return "Awesome result!"
31
+ ```
32
+ '''
33
+ def is_tool_plugin(obj: Any) -> bool:
34
+ """Check if an object is a tool plugin.
35
+
36
+ Args:
37
+ obj (Any): The object to check.
38
+
39
+ Returns:
40
+ bool: True if the object is a decorated tool plugin, False otherwise.
41
+ """
42
+ def get_plugin_metadata(tool_class: type[BaseTool]) -> dict[str, Any]:
43
+ """Get the plugin metadata from a decorated tool class.
44
+
45
+ Args:
46
+ tool_class (Type[BaseTool]): The tool class to get metadata from.
47
+
48
+ Returns:
49
+ dict[str, Any]: A dictionary of plugin metadata.
50
+
51
+ Raises:
52
+ ValueError: If the tool class is not a decorated tool plugin.
53
+ """
@@ -0,0 +1,71 @@
1
+ Metadata-Version: 2.1
2
+ Name: gllm-plugin
3
+ Version: 0.0.5.dev1
4
+ Summary:
5
+ Author: GenAI SDK Team
6
+ Author-email: gat-sdk@gdplabs.id
7
+ Requires-Python: >=3.11,<3.13
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Provides-Extra: flair
12
+ Requires-Dist: bosa-core
13
+ Requires-Dist: gllm-core
14
+ Requires-Dist: gllm-inference
15
+ Requires-Dist: gllm-pipeline
16
+ Requires-Dist: langchain (>=0.3.0,<0.4.0)
17
+ Requires-Dist: langchain-core (>=0.3.51)
18
+ Requires-Dist: semver (>=3.0.4,<4.0.0)
19
+ Description-Content-Type: text/markdown
20
+
21
+ # GDP Labs GenAI Plugin
22
+
23
+ ## Description
24
+
25
+ A library to implement Plugin architecture and integrate with existing pipelines.
26
+
27
+ ## Installation
28
+
29
+ 1. Python v3.11 or above:
30
+
31
+ You can install Python using [Miniconda](https://docs.anaconda.com/free/miniconda/index.html).
32
+
33
+ 2. [Poetry](https://python-poetry.org/docs/) v1.8.2:
34
+
35
+ You can install Poetry using cURL (you need Python to install Poetry):
36
+ ```bash
37
+ curl -sSL https://install.python-poetry.org | python3 -
38
+ ```
39
+
40
+ 3. Install the library using Poetry:
41
+
42
+ ```bash
43
+ # Add GDP Labs artifact repository as primary source
44
+ poetry source add gen-ai https://asia-southeast2-python.pkg.dev/gdp-labs/gen-ai/simple/ --priority=primary
45
+
46
+ # Add PyPI as supplemental source
47
+ poetry source add pypi --priority=supplemental
48
+
49
+ # Authenticate to GDP Labs SDK libraries (only gat@gdplabs.id group team has access)
50
+ poetry config http-basic.gen-ai oauth2accesstoken "$(gcloud auth print-access-token)"
51
+
52
+ # Latest version
53
+ poetry add gllm-plugin --source gen-ai
54
+
55
+ # Specific version
56
+ poetry add gllm-plugin@0.0.1b5 --source gen-ai
57
+ ```
58
+
59
+ 4. At this step, you can deactivate Miniconda environment as Poetry will create and manage its own virtual environment for you.
60
+ ```bash
61
+ conda deactivate
62
+ ```
63
+
64
+ 5. Try running the unit test to see if it's working:
65
+ ```bash
66
+ poetry run pytest
67
+ ```
68
+
69
+ ## Usage
70
+ For more information, please refer to the [PIPELINE.md](https://github.com/GDP-ADMIN/gen-ai-external/blob/main/libs/gllm-plugin/PIPELINE.md).
71
+
@@ -0,0 +1,20 @@
1
+ gllm_plugin/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ gllm_plugin/config/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ gllm_plugin/config/app_config.pyi,sha256=u8GKpA2RfbPcc_f-Cs1PSEXxzlMBXh9Lk_FCyNilzYA,233
4
+ gllm_plugin/config/constant.pyi,sha256=0n-BprzqEIepx8DkZHYEKeZat2VuZUweotwXOAG9hdc,564
5
+ gllm_plugin/pipeline/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ gllm_plugin/pipeline/base_pipeline_preset_config.pyi,sha256=iNzseVfo4UUPNSb1mMIGEjkqzA3Doa1EJHH_mFjqAEw,979
7
+ gllm_plugin/pipeline/pipeline_handler.pyi,sha256=z0i8K-36VoL_JffGPxGpGlacf3QBeb-z59zOcYvptL4,5996
8
+ gllm_plugin/pipeline/pipeline_plugin.pyi,sha256=KwL1DiUuE9TP1n_8hOi5D2qVpklX8m3MgtDkkGQhD8Q,3082
9
+ gllm_plugin/storage/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ gllm_plugin/storage/base_anonymizer_storage.pyi,sha256=Hv9WMbSakKePD_npOOD4fxXWxJt_qdISgCOkOUf2BqY,1818
11
+ gllm_plugin/storage/base_chat_history_storage.pyi,sha256=qgRC2clzOBs9WZ_ObIeAMQ114T_5CGkZOtfGADaofSs,11768
12
+ gllm_plugin/supported_models.pyi,sha256=4-yZ7F46fCBy6GuvZ6WukyEInUmoM7vwytp_8OCQkGM,5709
13
+ gllm_plugin/tools/__init__.pyi,sha256=7-eCKyzV0E_a17GyxWIhOMTzTgIsJCq-znVsbE35l1o,214
14
+ gllm_plugin/tools/decorators.pyi,sha256=i5DooMyw-7z59Gi9uUSyT4T5eUSne6uih64-CQ3F0aY,1708
15
+ gllm_plugin.build/.gitignore,sha256=aEiIwOuxfzdCmLZe4oB1JsBmCUxwG8x-u-HBCV9JT8E,1
16
+ gllm_plugin.cpython-311-darwin.so,sha256=vyBDpiy08RhjzcBJM83DF62zyg7LXsw8MFf-S-0Zsc8,739152
17
+ gllm_plugin.pyi,sha256=5Gz4wVBrRp8zcmqfPVeeR1sHP_exeLLc9tHsAneMzMM,661
18
+ gllm_plugin-0.0.5.dev1.dist-info/METADATA,sha256=_1HHuZNqEgMlDynXCQHXpVyMj57978uuyaHrks65Z1g,2137
19
+ gllm_plugin-0.0.5.dev1.dist-info/WHEEL,sha256=h9XAMipeFIBqDUT_aBB0JdEY0xFkdkjrW2Vy94TWs4I,106
20
+ gllm_plugin-0.0.5.dev1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.9.0
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-cp311-macosx_14_0_arm64
@@ -0,0 +1 @@
1
+ *
Binary file
gllm_plugin.pyi ADDED
@@ -0,0 +1,33 @@
1
+ # This file was generated by Nuitka
2
+
3
+ # Stubs included by default
4
+
5
+
6
+ __name__ = ...
7
+
8
+
9
+
10
+ # Modules used internally, to allow implicit dependencies to be seen:
11
+ import os
12
+ import typing
13
+ import pydantic
14
+ import enum
15
+ import bosa_core
16
+ import bosa_core.plugin
17
+ import bosa_core.plugin.handler
18
+ import gllm_core
19
+ import gllm_core.utils
20
+ import gllm_inference
21
+ import gllm_inference.catalog
22
+ import gllm_pipeline
23
+ import gllm_pipeline.pipeline
24
+ import gllm_pipeline.pipeline.pipeline
25
+ import abc
26
+ import bosa_core.plugin.plugin
27
+ import gllm_inference.catalog.catalog
28
+ import datetime
29
+ import typing_extensions
30
+ import base64
31
+ import inspect
32
+ import langchain_core
33
+ import langchain_core.tools