select-ai 1.2.0rc3__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.
select_ai/provider.py ADDED
@@ -0,0 +1,195 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Copyright (c) 2025, Oracle and/or its affiliates.
3
+ #
4
+ # Licensed under the Universal Permissive License v 1.0 as shown at
5
+ # http://oss.oracle.com/licenses/upl.
6
+ # -----------------------------------------------------------------------------
7
+
8
+ from dataclasses import dataclass
9
+ from typing import List, Optional, Union
10
+
11
+ from select_ai._abc import SelectAIDataClass
12
+ from select_ai._validations import enforce_types
13
+
14
+ from .db import async_cursor, cursor
15
+ from .sql import (
16
+ DISABLE_AI_PROFILE_DOMAIN_FOR_USER,
17
+ ENABLE_AI_PROFILE_DOMAIN_FOR_USER,
18
+ GRANT_PRIVILEGES_TO_USER,
19
+ REVOKE_PRIVILEGES_FROM_USER,
20
+ )
21
+
22
+ OPENAI = "openai"
23
+ COHERE = "cohere"
24
+ AZURE = "azure"
25
+ OCI = "oci"
26
+ GOOGLE = "google"
27
+ ANTHROPIC = "anthropic"
28
+ HUGGINGFACE = "huggingface"
29
+ AWS = "aws"
30
+
31
+
32
+ @dataclass
33
+ class Provider(SelectAIDataClass):
34
+ """
35
+ Base class for AI Provider
36
+
37
+ To create an object of Provider class, use any one of the concrete AI
38
+ provider implementations
39
+
40
+ :param str embedding_model: The embedding model, also known as a
41
+ transformer. Depending on the AI provider, the supported embedding models
42
+ vary
43
+ :param str model: The name of the LLM being used to generate
44
+ responses
45
+ :param str provider_name: The name of the provider being used
46
+ :param str provider_endpoint: Endpoint URL of the AI provider being used
47
+ :param str region: The cloud region of the Gen AI cluster
48
+
49
+ """
50
+
51
+ embedding_model: Optional[str] = None
52
+ model: Optional[str] = None
53
+ provider_name: Optional[str] = None
54
+ provider_endpoint: Optional[str] = None
55
+ region: Optional[str] = None
56
+
57
+ @classmethod
58
+ def create(cls, *, provider_name: Optional[str] = None, **kwargs):
59
+ for subclass in cls.__subclasses__():
60
+ if subclass.provider_name == provider_name:
61
+ return subclass(**kwargs)
62
+ return cls(**kwargs)
63
+
64
+ @classmethod
65
+ def key_alias(cls, k):
66
+ return {"provider": "provider_name", "provider_name": "provider"}.get(
67
+ k, k
68
+ )
69
+
70
+ @classmethod
71
+ def keys(cls):
72
+ return {
73
+ "provider",
74
+ "provider_name",
75
+ "embedding_model",
76
+ "model",
77
+ "region",
78
+ "provider_endpoint",
79
+ "azure_deployment_name",
80
+ "azure_embedding_deployment_name",
81
+ "azure_resource_name",
82
+ "oci_apiformat",
83
+ "oci_compartment_id",
84
+ "oci_endpoint_id",
85
+ "oci_runtimetype",
86
+ "aws_apiformat",
87
+ }
88
+
89
+
90
+ @dataclass
91
+ class AzureProvider(Provider):
92
+ """
93
+ Azure specific attributes
94
+
95
+ :param str azure_deployment_name: Name of the Azure OpenAI Service
96
+ deployed model.
97
+ :param str azure_embedding_deployment_name: Name of the Azure OpenAI
98
+ deployed embedding model.
99
+ :param str azure_resource_name: Name of the Azure OpenAI Service resource
100
+ """
101
+
102
+ provider_name: str = AZURE
103
+ azure_deployment_name: Optional[str] = None
104
+ azure_embedding_deployment_name: Optional[str] = None
105
+ azure_resource_name: Optional[str] = None
106
+
107
+ def __post_init__(self):
108
+ super().__post_init__()
109
+ self.provider_endpoint = f"{self.azure_resource_name}.openai.azure.com"
110
+
111
+
112
+ @dataclass
113
+ class OpenAIProvider(Provider):
114
+ """
115
+ OpenAI specific attributes
116
+ """
117
+
118
+ provider_name: str = OPENAI
119
+ provider_endpoint: Optional[str] = "api.openai.com"
120
+
121
+
122
+ @dataclass
123
+ class OCIGenAIProvider(Provider):
124
+ """
125
+ OCI Gen AI specific attributes
126
+
127
+ :param str oci_apiformat: Specifies the format in which the API expects
128
+ data to be sent and received. Supported values are 'COHERE' and 'GENERIC'
129
+ :param str oci_compartment_id: Specifies the OCID of the compartment you
130
+ are permitted to access when calling the OCI Generative AI service
131
+ :param str oci_endpoint_id: This attributes indicates the endpoint OCID
132
+ of the Oracle dedicated AI hosting cluster
133
+ :param str oci_runtimetype: This attribute indicates the runtime type of
134
+ the provided model. The supported values are 'COHERE' and 'LLAMA'
135
+ """
136
+
137
+ provider_name: str = OCI
138
+ oci_apiformat: Optional[str] = None
139
+ oci_compartment_id: Optional[str] = None
140
+ oci_endpoint_id: Optional[str] = None
141
+ oci_runtimetype: Optional[str] = None
142
+
143
+
144
+ @dataclass
145
+ class CohereProvider(Provider):
146
+ """
147
+ Cohere AI specific attributes
148
+ """
149
+
150
+ provider_name: str = COHERE
151
+ provider_endpoint = "api.cohere.ai"
152
+
153
+
154
+ @dataclass
155
+ class GoogleProvider(Provider):
156
+ """
157
+ Google AI specific attributes
158
+ """
159
+
160
+ provider_name: str = GOOGLE
161
+ provider_endpoint = "generativelanguage.googleapis.com"
162
+
163
+
164
+ @dataclass
165
+ class HuggingFaceProvider(Provider):
166
+ """
167
+ HuggingFace specific attributes
168
+ """
169
+
170
+ provider_name: str = HUGGINGFACE
171
+ provider_endpoint = "api-inference.huggingface.co"
172
+
173
+
174
+ @dataclass
175
+ class AWSProvider(Provider):
176
+ """
177
+ AWS specific attributes
178
+ """
179
+
180
+ provider_name: str = AWS
181
+ aws_apiformat: Optional[str] = None
182
+
183
+ def __post_init__(self):
184
+ super().__post_init__()
185
+ self.provider_endpoint = f"bedrock-runtime.{self.region}.amazonaws.com"
186
+
187
+
188
+ @dataclass
189
+ class AnthropicProvider(Provider):
190
+ """
191
+ Anthropic specific attributes
192
+ """
193
+
194
+ provider_name: str = ANTHROPIC
195
+ provider_endpoint = "api.anthropic.com"
select_ai/sql.py ADDED
@@ -0,0 +1,111 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Copyright (c) 2025, Oracle and/or its affiliates.
3
+ #
4
+ # Licensed under the Universal Permissive License v 1.0 as shown at
5
+ # http://oss.oracle.com/licenses/upl.
6
+ # -----------------------------------------------------------------------------
7
+
8
+ GRANT_PRIVILEGES_TO_USER = """
9
+ DECLARE
10
+ TYPE array_t IS VARRAY(4) OF VARCHAR2(60);
11
+ v_packages array_t;
12
+ BEGIN
13
+ v_packages := array_t(
14
+ 'DBMS_CLOUD',
15
+ 'DBMS_CLOUD_AI',
16
+ 'DBMS_CLOUD_AI_AGENT',
17
+ 'DBMS_CLOUD_PIPELINE'
18
+ );
19
+ FOR i in 1..v_packages.count LOOP
20
+ EXECUTE IMMEDIATE
21
+ 'GRANT EXECUTE ON ' || v_packages(i) || ' TO {0}';
22
+ END LOOP;
23
+ END;
24
+ """
25
+
26
+ REVOKE_PRIVILEGES_FROM_USER = """
27
+ DECLARE
28
+ TYPE array_t IS VARRAY(4) OF VARCHAR2(60);
29
+ v_packages array_t;
30
+ BEGIN
31
+ v_packages := array_t(
32
+ 'DBMS_CLOUD',
33
+ 'DBMS_CLOUD_AI',
34
+ 'DBMS_CLOUD_AI_AGENT',
35
+ 'DBMS_CLOUD_PIPELINE'
36
+ );
37
+ FOR i in 1..v_packages.count LOOP
38
+ EXECUTE IMMEDIATE
39
+ 'REVOKE EXECUTE ON ' || v_packages(i) || ' FROM {0}';
40
+ END LOOP;
41
+ END;
42
+ """
43
+
44
+ ENABLE_AI_PROFILE_DOMAIN_FOR_USER = """
45
+ BEGIN
46
+ DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
47
+ host => :host,
48
+ ace => xs$ace_type(privilege_list => xs$name_list('http'),
49
+ principal_name => :user,
50
+ principal_type => xs_acl.ptype_db)
51
+ );
52
+ END;
53
+ """
54
+
55
+ DISABLE_AI_PROFILE_DOMAIN_FOR_USER = """
56
+ BEGIN
57
+ DBMS_NETWORK_ACL_ADMIN.REMOVE_HOST_ACE(
58
+ host => :host,
59
+ ace => xs$ace_type(privilege_list => xs$name_list('http'),
60
+ principal_name => :user,
61
+ principal_type => xs_acl.ptype_db)
62
+ );
63
+ END;
64
+ """
65
+
66
+ GET_USER_AI_PROFILE_ATTRIBUTES = """
67
+ SELECT attribute_name, attribute_value
68
+ FROM USER_CLOUD_AI_PROFILE_ATTRIBUTES
69
+ WHERE profile_name = :profile_name
70
+ """
71
+
72
+ GET_USER_AI_PROFILE = """
73
+ SELECT profile_name, description
74
+ FROM USER_CLOUD_AI_PROFILES
75
+ WHERE profile_name = :profile_name
76
+ """
77
+
78
+
79
+ LIST_USER_AI_PROFILES = """
80
+ SELECT profile_name, description
81
+ FROM USER_CLOUD_AI_PROFILES
82
+ WHERE REGEXP_LIKE(profile_name, :profile_name_pattern, 'i')
83
+ """
84
+
85
+ LIST_USER_VECTOR_INDEXES = """
86
+ SELECT v.index_name, v.description
87
+ FROM USER_CLOUD_VECTOR_INDEXES v
88
+ WHERE REGEXP_LIKE(v.index_name, :index_name_pattern, 'i')
89
+ """
90
+
91
+ GET_USER_VECTOR_INDEX_ATTRIBUTES = """
92
+ SELECT attribute_name, attribute_value
93
+ FROM USER_CLOUD_VECTOR_INDEX_ATTRIBUTES
94
+ WHERE INDEX_NAME = :index_name
95
+ """
96
+
97
+ LIST_USER_CONVERSATIONS = """
98
+ SELECT conversation_id,
99
+ conversation_title,
100
+ description,
101
+ retention_days
102
+ from USER_CLOUD_AI_CONVERSATIONS
103
+ """
104
+
105
+ GET_USER_CONVERSATION_ATTRIBUTES = """
106
+ SELECT conversation_title,
107
+ description,
108
+ retention_days
109
+ from USER_CLOUD_AI_CONVERSATIONS
110
+ WHERE conversation_id = :conversation_id
111
+ """
select_ai/summary.py ADDED
@@ -0,0 +1,61 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Copyright (c) 2025, Oracle and/or its affiliates.
3
+ #
4
+ # Licensed under the Universal Permissive License v 1.0 as shown at
5
+ # http://oss.oracle.com/licenses/upl.
6
+ # -----------------------------------------------------------------------------
7
+
8
+ from dataclasses import dataclass
9
+ from typing import Optional
10
+
11
+ from select_ai._abc import SelectAIDataClass
12
+ from select_ai._enums import StrEnum
13
+
14
+
15
+ class Style(StrEnum):
16
+
17
+ PARAGRAPH = "paragraph"
18
+ LIST = "list"
19
+
20
+
21
+ class ChunkProcessingMethod(StrEnum):
22
+
23
+ ITERATIVE_REFINEMENT = "iterative_refinement"
24
+ MAP_REDUCE = "map_reduce"
25
+
26
+
27
+ class ExtractivenessLevel(StrEnum):
28
+
29
+ LOW = "low"
30
+ MEDIUM = "medium"
31
+ HIGH = "high"
32
+
33
+
34
+ @dataclass
35
+ class SummaryParams(SelectAIDataClass):
36
+ """
37
+ Customize summary generation using these parameters
38
+
39
+ :param int min_words: approximate minimum number of words the generated
40
+ summary is expected to contain.
41
+
42
+ :param int max_words: approximate maximum number of words the generated
43
+ summary is expected to contain.
44
+
45
+ :param select_ai.summary.Style summary_style: Specifies the format
46
+ style for the summary
47
+
48
+ :param select_ai.summary.ChunkProcessingMethod chunk_processing_method:
49
+ When the text exceeds the token limit that the LLM can process, it must
50
+ be split into manageable chunks
51
+
52
+ :param select_ai.summary.ExtractivenessLevel extractiveness_level:
53
+ Determines how closely the summary follows the original wording
54
+ of the input
55
+ """
56
+
57
+ min_words: Optional[int] = None
58
+ max_words: Optional[int] = None
59
+ summary_style: Optional[Style] = None
60
+ chunk_processing_method: Optional[ChunkProcessingMethod] = None
61
+ extractiveness_level: Optional[ExtractivenessLevel] = None
@@ -0,0 +1,90 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Copyright (c) 2025, Oracle and/or its affiliates.
3
+ #
4
+ # Licensed under the Universal Permissive License v 1.0 as shown at
5
+ # http://oss.oracle.com/licenses/upl.
6
+ # -----------------------------------------------------------------------------
7
+
8
+ import json
9
+ from dataclasses import dataclass
10
+ from typing import List, Mapping, Optional
11
+
12
+ from select_ai._abc import SelectAIDataClass
13
+
14
+
15
+ @dataclass
16
+ class SyntheticDataParams(SelectAIDataClass):
17
+ """Optional parameters to control generation of synthetic data
18
+
19
+ :param int sample_rows: number of rows from the table to use as a sample
20
+ to guide the LLM in data generation
21
+
22
+ :param bool table_statistics: Enable or disable the use of table
23
+ statistics information. Default value is False
24
+
25
+ :param str priority: Assign a priority value that defines the number of
26
+ parallel requests sent to the LLM for generating synthetic data.
27
+ Tasks with a higher priority will consume more database resources and
28
+ complete faster. Possible values are: HIGH, MEDIUM, LOW
29
+
30
+ :param bool comments: Enable or disable sending comments to the LLM to
31
+ guide data generation. Default value is False
32
+
33
+ """
34
+
35
+ sample_rows: Optional[int] = None
36
+ table_statistics: Optional[bool] = False
37
+ priority: Optional[str] = "HIGH"
38
+ comments: Optional[bool] = False
39
+
40
+
41
+ @dataclass
42
+ class SyntheticDataAttributes(SelectAIDataClass):
43
+ """Attributes to control generation of synthetic data
44
+
45
+ :param str object_name: Table name to populate synthetic data
46
+ :param List[Mapping] object_list: Use this to generate synthetic data
47
+ on multiple tables
48
+ :param str owner_name: Database user who owns the referenced object.
49
+ Default value is connected user's schema
50
+ :param int record_count: Number of records to generate
51
+ :param str user_prompt: User prompt to guide generation of synthetic data
52
+ For e.g. "the release date for the movies should be in 2019"
53
+
54
+ """
55
+
56
+ object_name: Optional[str] = None
57
+ object_list: Optional[List[Mapping]] = None
58
+ owner_name: Optional[str] = None
59
+ params: Optional[SyntheticDataParams] = None
60
+ record_count: Optional[int] = None
61
+ user_prompt: Optional[str] = None
62
+
63
+ def __post_init__(self):
64
+ if self.params and not isinstance(self.params, SyntheticDataParams):
65
+ raise TypeError(
66
+ "'params' must be an object of" " type SyntheticDataParams'"
67
+ )
68
+
69
+ def dict(self, exclude_null=True):
70
+ attributes = {}
71
+ for k, v in self.__dict__.items():
72
+ if v is not None or not exclude_null:
73
+ if isinstance(v, SyntheticDataParams):
74
+ attributes[k] = v.json(exclude_null=exclude_null)
75
+ elif isinstance(v, List):
76
+ attributes[k] = json.dumps(v)
77
+ else:
78
+ attributes[k] = v
79
+ return attributes
80
+
81
+ def prepare(self):
82
+ if self.object_name and self.object_list:
83
+ raise ValueError("Both object_name and object_list cannot be set")
84
+
85
+ if not self.object_name and not self.object_list:
86
+ raise ValueError(
87
+ "One of object_name and object_list should be set"
88
+ )
89
+
90
+ return self.dict()