trustgraph-vertexai 1.2.10__tar.gz → 1.2.12__tar.gz

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.

Potentially problematic release.


This version of trustgraph-vertexai might be problematic. Click here for more details.

Files changed (16) hide show
  1. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/PKG-INFO +2 -1
  2. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/pyproject.toml +1 -0
  3. trustgraph_vertexai-1.2.12/trustgraph/model/text_completion/vertexai/llm.py +241 -0
  4. trustgraph_vertexai-1.2.12/trustgraph/vertexai_version.py +1 -0
  5. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/trustgraph_vertexai.egg-info/PKG-INFO +2 -1
  6. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/trustgraph_vertexai.egg-info/requires.txt +1 -0
  7. trustgraph_vertexai-1.2.10/trustgraph/model/text_completion/vertexai/llm.py +0 -202
  8. trustgraph_vertexai-1.2.10/trustgraph/vertexai_version.py +0 -1
  9. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/README.md +0 -0
  10. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/setup.cfg +0 -0
  11. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/trustgraph/model/text_completion/vertexai/__init__.py +0 -0
  12. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/trustgraph/model/text_completion/vertexai/__main__.py +0 -0
  13. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/trustgraph_vertexai.egg-info/SOURCES.txt +0 -0
  14. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/trustgraph_vertexai.egg-info/dependency_links.txt +0 -0
  15. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/trustgraph_vertexai.egg-info/entry_points.txt +0 -0
  16. {trustgraph_vertexai-1.2.10 → trustgraph_vertexai-1.2.12}/trustgraph_vertexai.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trustgraph-vertexai
3
- Version: 1.2.10
3
+ Version: 1.2.12
4
4
  Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
5
5
  Author-email: "trustgraph.ai" <security@trustgraph.ai>
6
6
  Project-URL: Homepage, https://github.com/trustgraph-ai/trustgraph
@@ -12,5 +12,6 @@ Requires-Dist: trustgraph-base<1.3,>=1.2
12
12
  Requires-Dist: pulsar-client
13
13
  Requires-Dist: google-cloud-aiplatform
14
14
  Requires-Dist: prometheus-client
15
+ Requires-Dist: anthropic
15
16
 
16
17
  See https://trustgraph.ai/
@@ -14,6 +14,7 @@ dependencies = [
14
14
  "pulsar-client",
15
15
  "google-cloud-aiplatform",
16
16
  "prometheus-client",
17
+ "anthropic",
17
18
  ]
18
19
  classifiers = [
19
20
  "Programming Language :: Python :: 3",
@@ -0,0 +1,241 @@
1
+ """
2
+ Simple LLM service, performs text prompt completion using VertexAI on
3
+ Google Cloud. Input is prompt, output is response.
4
+ Supports both Google's Gemini models and Anthropic's Claude models.
5
+ """
6
+
7
+ #
8
+ # Somewhat perplexed by the Google Cloud SDK choices. We're going off this
9
+ # one, which uses the google-cloud-aiplatform library:
10
+ # https://cloud.google.com/python/docs/reference/vertexai/1.94.0
11
+ # It seems it is possible to invoke VertexAI from the google-genai
12
+ # SDK too:
13
+ # https://googleapis.github.io/python-genai/genai.html#module-genai.client
14
+ # That would make this code look very much like the GoogleAIStudio
15
+ # code. And maybe not reliant on the google-cloud-aiplatform library?
16
+ #
17
+ # This module's imports bring in a lot of libraries.
18
+
19
+ from google.oauth2 import service_account
20
+ import google.auth
21
+ import vertexai
22
+ import logging
23
+
24
+ # Why is preview here?
25
+ from vertexai.generative_models import (
26
+ Content, FunctionDeclaration, GenerativeModel, GenerationConfig,
27
+ HarmCategory, HarmBlockThreshold, Part, Tool, SafetySetting,
28
+ )
29
+
30
+ # Added for Anthropic model support
31
+ from anthropic import AnthropicVertex, RateLimitError
32
+
33
+ from .... exceptions import TooManyRequests
34
+ from .... base import LlmService, LlmResult
35
+
36
+ # Module logger
37
+ logger = logging.getLogger(__name__)
38
+
39
+ default_ident = "text-completion"
40
+
41
+ default_model = 'gemini-1.5-flash-001'
42
+ default_region = 'us-central1'
43
+ default_temperature = 0.0
44
+ default_max_output = 8192
45
+ default_private_key = "private.json"
46
+
47
+ class Processor(LlmService):
48
+
49
+ def __init__(self, **params):
50
+
51
+ region = params.get("region", default_region)
52
+ model = params.get("model", default_model)
53
+ private_key = params.get("private_key", default_private_key)
54
+ temperature = params.get("temperature", default_temperature)
55
+ max_output = params.get("max_output", default_max_output)
56
+
57
+ if private_key is None:
58
+ logger.warning("Private key file not specified, using Application Default Credentials")
59
+
60
+ super(Processor, self).__init__(**params)
61
+
62
+ self.model = model
63
+ self.is_anthropic = 'claude' in self.model.lower()
64
+
65
+ # Shared parameters for both model types
66
+ self.api_params = {
67
+ "temperature": temperature,
68
+ "top_p": 1.0,
69
+ "top_k": 32,
70
+ "max_output_tokens": max_output,
71
+ }
72
+
73
+ logger.info("Initializing VertexAI...")
74
+
75
+ # Unified credential and project ID loading
76
+ if private_key:
77
+ credentials = (
78
+ service_account.Credentials.from_service_account_file(
79
+ private_key
80
+ )
81
+ )
82
+ project_id = credentials.project_id
83
+ else:
84
+ credentials, project_id = google.auth.default()
85
+
86
+ if not project_id:
87
+ raise RuntimeError(
88
+ "Could not determine Google Cloud project ID. "
89
+ "Ensure it's set in your environment or service account."
90
+ )
91
+
92
+ # Initialize the appropriate client based on the model type
93
+ if self.is_anthropic:
94
+ logger.info(f"Initializing Anthropic model '{model}' via AnthropicVertex SDK")
95
+ # Initialize AnthropicVertex with credentials if provided, otherwise use ADC
96
+ anthropic_kwargs = {'region': region, 'project_id': project_id}
97
+ if credentials and private_key: # Pass credentials only if from a file
98
+ anthropic_kwargs['credentials'] = credentials
99
+ logger.debug(f"Using service account credentials for Anthropic model")
100
+ else:
101
+ logger.debug(f"Using Application Default Credentials for Anthropic model")
102
+
103
+ self.llm = AnthropicVertex(**anthropic_kwargs)
104
+ else:
105
+ # For Gemini models, initialize the Vertex AI SDK
106
+ logger.info(f"Initializing Google model '{model}' via Vertex AI SDK")
107
+ init_kwargs = {'location': region, 'project': project_id}
108
+ if credentials and private_key: # Pass credentials only if from a file
109
+ init_kwargs['credentials'] = credentials
110
+
111
+ vertexai.init(**init_kwargs)
112
+
113
+ self.llm = GenerativeModel(model)
114
+
115
+ self.generation_config = GenerationConfig(
116
+ temperature=temperature,
117
+ top_p=1.0,
118
+ top_k=10,
119
+ candidate_count=1,
120
+ max_output_tokens=max_output,
121
+ )
122
+
123
+ # Block none doesn't seem to work
124
+ block_level = HarmBlockThreshold.BLOCK_ONLY_HIGH
125
+ # block_level = HarmBlockThreshold.BLOCK_NONE
126
+
127
+ self.safety_settings = [
128
+ SafetySetting(
129
+ category = HarmCategory.HARM_CATEGORY_HARASSMENT,
130
+ threshold = block_level,
131
+ ),
132
+ SafetySetting(
133
+ category = HarmCategory.HARM_CATEGORY_HATE_SPEECH,
134
+ threshold = block_level,
135
+ ),
136
+ SafetySetting(
137
+ category = HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
138
+ threshold = block_level,
139
+ ),
140
+ SafetySetting(
141
+ category = HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
142
+ threshold = block_level,
143
+ ),
144
+ ]
145
+
146
+
147
+ logger.info("VertexAI initialization complete")
148
+
149
+ async def generate_content(self, system, prompt):
150
+
151
+ try:
152
+ if self.is_anthropic:
153
+ # Anthropic API uses a dedicated system prompt
154
+ logger.debug("Sending request to Anthropic model...")
155
+ response = self.llm.messages.create(
156
+ model=self.model,
157
+ system=system,
158
+ messages=[{"role": "user", "content": prompt}],
159
+ max_tokens=self.api_params['max_output_tokens'],
160
+ temperature=self.api_params['temperature'],
161
+ top_p=self.api_params['top_p'],
162
+ top_k=self.api_params['top_k'],
163
+ )
164
+
165
+ resp = LlmResult(
166
+ text=response.content[0].text,
167
+ in_token=response.usage.input_tokens,
168
+ out_token=response.usage.output_tokens,
169
+ model=self.model
170
+ )
171
+ else:
172
+ # Gemini API combines system and user prompts
173
+ logger.debug("Sending request to Gemini model...")
174
+ full_prompt = system + "\n\n" + prompt
175
+
176
+ response = self.llm.generate_content(
177
+ full_prompt, generation_config = self.generation_config,
178
+ safety_settings = self.safety_settings,
179
+ )
180
+
181
+ resp = LlmResult(
182
+ text = response.text,
183
+ in_token = response.usage_metadata.prompt_token_count,
184
+ out_token = response.usage_metadata.candidates_token_count,
185
+ model = self.model
186
+ )
187
+
188
+ logger.info(f"Input Tokens: {resp.in_token}")
189
+ logger.info(f"Output Tokens: {resp.out_token}")
190
+ logger.debug("Send response...")
191
+
192
+ return resp
193
+
194
+ except (google.api_core.exceptions.ResourceExhausted, RateLimitError) as e:
195
+ logger.warning(f"Hit rate limit: {e}")
196
+ # Leave rate limit retries to the base handler
197
+ raise TooManyRequests()
198
+
199
+ except Exception as e:
200
+ # Apart from rate limits, treat all exceptions as unrecoverable
201
+ logger.error(f"VertexAI LLM exception: {e}", exc_info=True)
202
+ raise e
203
+
204
+ @staticmethod
205
+ def add_args(parser):
206
+
207
+ LlmService.add_args(parser)
208
+
209
+ parser.add_argument(
210
+ '-m', '--model',
211
+ default=default_model,
212
+ help=f'LLM model (e.g., gemini-1.5-flash-001, claude-3-sonnet@20240229) (default: {default_model})'
213
+ )
214
+
215
+ parser.add_argument(
216
+ '-k', '--private-key',
217
+ help=f'Google Cloud private JSON file (optional, uses ADC if not provided)'
218
+ )
219
+
220
+ parser.add_argument(
221
+ '-r', '--region',
222
+ default=default_region,
223
+ help=f'Google Cloud region (default: {default_region})',
224
+ )
225
+
226
+ parser.add_argument(
227
+ '-t', '--temperature',
228
+ type=float,
229
+ default=default_temperature,
230
+ help=f'LLM temperature parameter (default: {default_temperature})'
231
+ )
232
+
233
+ parser.add_argument(
234
+ '-x', '--max-output',
235
+ type=int,
236
+ default=default_max_output,
237
+ help=f'LLM max output tokens (default: {default_max_output})'
238
+ )
239
+
240
+ def run():
241
+ Processor.launch(default_ident, __doc__)
@@ -0,0 +1 @@
1
+ __version__ = "1.2.12"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trustgraph-vertexai
3
- Version: 1.2.10
3
+ Version: 1.2.12
4
4
  Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
5
5
  Author-email: "trustgraph.ai" <security@trustgraph.ai>
6
6
  Project-URL: Homepage, https://github.com/trustgraph-ai/trustgraph
@@ -12,5 +12,6 @@ Requires-Dist: trustgraph-base<1.3,>=1.2
12
12
  Requires-Dist: pulsar-client
13
13
  Requires-Dist: google-cloud-aiplatform
14
14
  Requires-Dist: prometheus-client
15
+ Requires-Dist: anthropic
15
16
 
16
17
  See https://trustgraph.ai/
@@ -2,3 +2,4 @@ trustgraph-base<1.3,>=1.2
2
2
  pulsar-client
3
3
  google-cloud-aiplatform
4
4
  prometheus-client
5
+ anthropic
@@ -1,202 +0,0 @@
1
-
2
- """
3
- Simple LLM service, performs text prompt completion using VertexAI on
4
- Google Cloud. Input is prompt, output is response.
5
- """
6
-
7
- #
8
- # Somewhat perplexed by the Google Cloud SDK choices. We're going off this
9
- # one, which uses the google-cloud-aiplatform library:
10
- # https://cloud.google.com/python/docs/reference/vertexai/1.94.0
11
- # It seems it is possible to invoke VertexAI from the google-genai
12
- # SDK too:
13
- # https://googleapis.github.io/python-genai/genai.html#module-genai.client
14
- # That would make this code look very much like the GoogleAIStudio
15
- # code. And maybe not reliant on the google-cloud-aiplatform library?
16
- #
17
- # This module's imports bring in a lot of libraries.
18
-
19
- from google.oauth2 import service_account
20
- import google
21
- import vertexai
22
- import logging
23
-
24
- # Why is preview here?
25
- from vertexai.generative_models import (
26
- Content, FunctionDeclaration, GenerativeModel, GenerationConfig,
27
- HarmCategory, HarmBlockThreshold, Part, Tool, SafetySetting,
28
- )
29
-
30
- from .... exceptions import TooManyRequests
31
- from .... base import LlmService, LlmResult
32
-
33
- # Module logger
34
- logger = logging.getLogger(__name__)
35
-
36
- default_ident = "text-completion"
37
-
38
- default_model = 'gemini-2.0-flash-001'
39
- default_region = 'us-central1'
40
- default_temperature = 0.0
41
- default_max_output = 8192
42
- default_private_key = "private.json"
43
-
44
- class Processor(LlmService):
45
-
46
- def __init__(self, **params):
47
-
48
- region = params.get("region", default_region)
49
- model = params.get("model", default_model)
50
- private_key = params.get("private_key", default_private_key)
51
- temperature = params.get("temperature", default_temperature)
52
- max_output = params.get("max_output", default_max_output)
53
-
54
- if private_key is None:
55
- raise RuntimeError("Private key file not specified")
56
-
57
- super(Processor, self).__init__(**params)
58
-
59
- self.parameters = {
60
- "temperature": temperature,
61
- "top_p": 1.0,
62
- "top_k": 32,
63
- "candidate_count": 1,
64
- "max_output_tokens": max_output,
65
- }
66
-
67
- self.generation_config = GenerationConfig(
68
- temperature=temperature,
69
- top_p=1.0,
70
- top_k=10,
71
- candidate_count=1,
72
- max_output_tokens=max_output,
73
- )
74
-
75
- # Block none doesn't seem to work
76
- block_level = HarmBlockThreshold.BLOCK_ONLY_HIGH
77
- # block_level = HarmBlockThreshold.BLOCK_NONE
78
-
79
- self.safety_settings = [
80
- SafetySetting(
81
- category = HarmCategory.HARM_CATEGORY_HARASSMENT,
82
- threshold = block_level,
83
- ),
84
- SafetySetting(
85
- category = HarmCategory.HARM_CATEGORY_HATE_SPEECH,
86
- threshold = block_level,
87
- ),
88
- SafetySetting(
89
- category = HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
90
- threshold = block_level,
91
- ),
92
- SafetySetting(
93
- category = HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
94
- threshold = block_level,
95
- ),
96
- ]
97
-
98
- logger.info("Initializing VertexAI...")
99
-
100
- if private_key:
101
- credentials = (
102
- service_account.Credentials.from_service_account_file(
103
- private_key
104
- )
105
- )
106
- else:
107
- credentials = None
108
-
109
- if credentials:
110
- vertexai.init(
111
- location=region,
112
- credentials=credentials,
113
- project=credentials.project_id,
114
- )
115
- else:
116
- vertexai.init(
117
- location=region
118
- )
119
-
120
- logger.info(f"Initializing model {model}")
121
- self.llm = GenerativeModel(model)
122
- self.model = model
123
-
124
- logger.info("VertexAI initialization complete")
125
-
126
- async def generate_content(self, system, prompt):
127
-
128
- try:
129
-
130
- prompt = system + "\n\n" + prompt
131
-
132
- response = self.llm.generate_content(
133
- prompt, generation_config = self.generation_config,
134
- safety_settings = self.safety_settings,
135
- )
136
-
137
- resp = LlmResult(
138
- text = response.text,
139
- in_token = response.usage_metadata.prompt_token_count,
140
- out_token = response.usage_metadata.candidates_token_count,
141
- model = self.model
142
- )
143
-
144
- logger.info(f"Input Tokens: {resp.in_token}")
145
- logger.info(f"Output Tokens: {resp.out_token}")
146
-
147
- logger.debug("Send response...")
148
-
149
- return resp
150
-
151
- except google.api_core.exceptions.ResourceExhausted as e:
152
-
153
- logger.warning(f"Hit rate limit: {e}")
154
-
155
- # Leave rate limit retries to the base handler
156
- raise TooManyRequests()
157
-
158
- except Exception as e:
159
-
160
- # Apart from rate limits, treat all exceptions as unrecoverable
161
- logger.error(f"VertexAI LLM exception: {e}", exc_info=True)
162
- raise e
163
-
164
- @staticmethod
165
- def add_args(parser):
166
-
167
- LlmService.add_args(parser)
168
-
169
- parser.add_argument(
170
- '-m', '--model',
171
- default=default_model,
172
- help=f'LLM model (default: {default_model})'
173
- )
174
-
175
- parser.add_argument(
176
- '-k', '--private-key',
177
- help=f'Google Cloud private JSON file'
178
- )
179
-
180
- parser.add_argument(
181
- '-r', '--region',
182
- default=default_region,
183
- help=f'Google Cloud region (default: {default_region})',
184
- )
185
-
186
- parser.add_argument(
187
- '-t', '--temperature',
188
- type=float,
189
- default=default_temperature,
190
- help=f'LLM temperature parameter (default: {default_temperature})'
191
- )
192
-
193
- parser.add_argument(
194
- '-x', '--max-output',
195
- type=int,
196
- default=default_max_output,
197
- help=f'LLM max output tokens (default: {default_max_output})'
198
- )
199
-
200
- def run():
201
- Processor.launch(default_ident, __doc__)
202
-
@@ -1 +0,0 @@
1
- __version__ = "1.2.10"