pangea-sdk 6.6.0__tar.gz → 6.7.0__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.
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/PKG-INFO +3 -3
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/__init__.py +1 -1
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/ai_guard.py +81 -1
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/prompt_guard.py +2 -1
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/ai_guard.py +210 -17
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/prompt_guard.py +9 -7
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pyproject.toml +7 -7
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/README.md +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/_constants.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/_typing.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/__init__.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/file_uploader.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/request.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/__init__.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/audit.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/authn.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/authz.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/base.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/embargo.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/file_scan.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/intel.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/redact.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/sanitize.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/share.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/asyncio/services/vault.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/audit_logger.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/config.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/crypto/rsa.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/deep_verify.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/deprecated.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/dump_audit.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/exceptions.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/file_uploader.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/py.typed +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/request.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/response.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/__init__.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/audit/audit.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/audit/exceptions.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/audit/models.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/audit/signing.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/audit/util.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/authn/authn.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/authn/models.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/authz.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/base.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/embargo.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/file_scan.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/intel.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/redact.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/sanitize.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/share/file_format.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/share/share.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/vault/models/asymmetric.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/vault/models/common.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/vault/models/keys.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/vault/models/secret.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/vault/models/symmetric.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/services/vault/vault.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/tools.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/utils.py +0 -0
- {pangea_sdk-6.6.0 → pangea_sdk-6.7.0}/pangea/verify_audit.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pangea-sdk
|
3
|
-
Version: 6.
|
3
|
+
Version: 6.7.0
|
4
4
|
Summary: Pangea API SDK
|
5
5
|
Keywords: Pangea,SDK,Audit
|
6
6
|
Author: Glenn Gallien
|
@@ -9,10 +9,10 @@ License-Expression: MIT
|
|
9
9
|
Classifier: Topic :: Software Development
|
10
10
|
Classifier: Topic :: Software Development :: Libraries
|
11
11
|
Requires-Dist: aiohttp>=3.12.15,<4.0.0
|
12
|
-
Requires-Dist: cryptography>=45.0.
|
12
|
+
Requires-Dist: cryptography>=45.0.7,<46.0.0
|
13
13
|
Requires-Dist: deprecated>=1.2.18,<2.0.0
|
14
14
|
Requires-Dist: google-crc32c>=1.7.1,<2.0.0
|
15
|
-
Requires-Dist: pydantic>=2.11.
|
15
|
+
Requires-Dist: pydantic>=2.11.9,<3.0.0
|
16
16
|
Requires-Dist: python-dateutil>=2.9.0.post0,<3.0.0
|
17
17
|
Requires-Dist: requests>=2.32.5,<3.0.0
|
18
18
|
Requires-Dist: requests-toolbelt>=1.0.0,<2.0.0
|
@@ -1,12 +1,16 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from collections.abc import Sequence
|
3
|
+
from collections.abc import Mapping, Sequence
|
4
4
|
from typing import overload
|
5
5
|
|
6
|
+
from typing_extensions import Any, Literal
|
7
|
+
|
6
8
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
7
9
|
from pangea.config import PangeaConfig
|
8
10
|
from pangea.response import PangeaResponse
|
9
11
|
from pangea.services.ai_guard import (
|
12
|
+
ExtraInfo,
|
13
|
+
GuardResult,
|
10
14
|
LogFields,
|
11
15
|
McpToolsMessage,
|
12
16
|
Message,
|
@@ -194,3 +198,79 @@ class AIGuardAsync(ServiceBaseAsync):
|
|
194
198
|
) # type: ignore[assignment]
|
195
199
|
|
196
200
|
return response
|
201
|
+
|
202
|
+
async def guard(
|
203
|
+
self,
|
204
|
+
input: Mapping[str, Any],
|
205
|
+
*,
|
206
|
+
recipe: str | None = None,
|
207
|
+
debug: bool | None = None,
|
208
|
+
overrides: Overrides | None = None,
|
209
|
+
app_id: str | None = None,
|
210
|
+
actor_id: str | None = None,
|
211
|
+
llm_provider: str | None = None,
|
212
|
+
model: str | None = None,
|
213
|
+
model_version: str | None = None,
|
214
|
+
request_token_count: int | None = None,
|
215
|
+
response_token_count: int | None = None,
|
216
|
+
source_ip: str | None = None,
|
217
|
+
source_location: str | None = None,
|
218
|
+
tenant_id: str | None = None,
|
219
|
+
event_type: Literal["input", "output", "tool_input", "tool_output", "tool_listing"] | None = None,
|
220
|
+
collector_instance_id: str | None = None,
|
221
|
+
extra_info: ExtraInfo | None = None,
|
222
|
+
count_tokens: bool | None = None,
|
223
|
+
) -> PangeaResponse[GuardResult]:
|
224
|
+
"""
|
225
|
+
Guard LLM input and output
|
226
|
+
|
227
|
+
Analyze and redact content to avoid manipulation of the model, addition
|
228
|
+
of malicious content, and other undesirable data transfers.
|
229
|
+
|
230
|
+
OperationId: ai_guard_post_v1_guard
|
231
|
+
|
232
|
+
Args:
|
233
|
+
input: 'messages' (required) contains Prompt content and role array
|
234
|
+
in JSON format. The `content` is the multimodal text or image
|
235
|
+
input that will be analyzed. Additional properties such as
|
236
|
+
'tools' may be provided for analysis.
|
237
|
+
recipe: Recipe key of a configuration of data types and settings defined in the Pangea User Console. It specifies the rules that are to be applied to the text, such as defang malicious URLs.
|
238
|
+
debug: Setting this value to true will provide a detailed analysis of the text data
|
239
|
+
app_name: Name of source application.
|
240
|
+
llm_provider: Underlying LLM. Example: 'OpenAI'.
|
241
|
+
model: Model used to perform the event. Example: 'gpt'.
|
242
|
+
model_version: Model version used to perform the event. Example: '3.5'.
|
243
|
+
request_token_count: Number of tokens in the request.
|
244
|
+
response_token_count: Number of tokens in the response.
|
245
|
+
source_ip: IP address of user or app or agent.
|
246
|
+
source_location: Location of user or app or agent.
|
247
|
+
tenant_id: For gateway-like integrations with multi-tenant support.
|
248
|
+
event_type: (AIDR) Event Type.
|
249
|
+
collector_instance_id: (AIDR) collector instance id.
|
250
|
+
extra_info: (AIDR) Logging schema.
|
251
|
+
count_tokens: Provide input and output token count.
|
252
|
+
"""
|
253
|
+
return await self.request.post(
|
254
|
+
"v1/guard",
|
255
|
+
GuardResult,
|
256
|
+
data={
|
257
|
+
"input": input,
|
258
|
+
"recipe": recipe,
|
259
|
+
"debug": debug,
|
260
|
+
"overrides": overrides,
|
261
|
+
"app_id": app_id,
|
262
|
+
"actor_id": actor_id,
|
263
|
+
"llm_provider": llm_provider,
|
264
|
+
"model": model,
|
265
|
+
"model_version": model_version,
|
266
|
+
"request_token_count": request_token_count,
|
267
|
+
"response_token_count": response_token_count,
|
268
|
+
"source_ip": source_ip,
|
269
|
+
"source_location": source_location,
|
270
|
+
"tenant_id": tenant_id,
|
271
|
+
"event_type": event_type,
|
272
|
+
"collector_instance_id": collector_instance_id,
|
273
|
+
"extra_info": extra_info,
|
274
|
+
"count_tokens": count_tokens,
|
275
|
+
},
|
276
|
+
)
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from typing import TYPE_CHECKING
|
4
4
|
|
5
|
+
from pangea._typing import SequenceNotStr
|
5
6
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
6
7
|
from pangea.config import PangeaConfig
|
7
8
|
from pangea.services.prompt_guard import GuardResult, Message
|
@@ -58,7 +59,7 @@ class PromptGuardAsync(ServiceBaseAsync):
|
|
58
59
|
self,
|
59
60
|
messages: Iterable[Message],
|
60
61
|
*,
|
61
|
-
analyzers:
|
62
|
+
analyzers: SequenceNotStr[str] | None = None,
|
62
63
|
classify: bool | None = None,
|
63
64
|
) -> PangeaResponse[GuardResult]:
|
64
65
|
"""
|
@@ -1,7 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from collections.abc import Sequence
|
4
|
-
from typing import Any, Generic, Literal, Optional, overload
|
3
|
+
from collections.abc import Mapping, Sequence
|
4
|
+
from typing import Annotated, Any, Generic, Literal, Optional, overload
|
5
|
+
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field, RootModel
|
5
7
|
|
6
8
|
from pangea._typing import T
|
7
9
|
from pangea.config import PangeaConfig
|
@@ -280,26 +282,26 @@ class CodeDetectionResult(APIResponseModel):
|
|
280
282
|
"""The action taken by this Detector"""
|
281
283
|
|
282
284
|
|
283
|
-
class
|
285
|
+
class GuardDetector(APIResponseModel, Generic[T]):
|
284
286
|
detected: Optional[bool] = None
|
285
287
|
data: Optional[T] = None
|
286
288
|
|
287
289
|
|
288
290
|
class TextGuardDetectors(APIResponseModel):
|
289
|
-
code_detection: Optional[
|
290
|
-
competitors: Optional[
|
291
|
-
custom_entity: Optional[
|
292
|
-
gibberish: Optional[
|
293
|
-
hardening: Optional[
|
294
|
-
language_detection: Optional[
|
295
|
-
malicious_entity: Optional[
|
296
|
-
pii_entity: Optional[
|
297
|
-
profanity_and_toxicity: Optional[
|
298
|
-
prompt_injection: Optional[
|
299
|
-
secrets_detection: Optional[
|
300
|
-
selfharm: Optional[
|
301
|
-
sentiment: Optional[
|
302
|
-
topic: Optional[
|
291
|
+
code_detection: Optional[GuardDetector[CodeDetectionResult]] = None
|
292
|
+
competitors: Optional[GuardDetector[object]] = None
|
293
|
+
custom_entity: Optional[GuardDetector[object]] = None
|
294
|
+
gibberish: Optional[GuardDetector[object]] = None
|
295
|
+
hardening: Optional[GuardDetector[object]] = None
|
296
|
+
language_detection: Optional[GuardDetector[LanguageDetectionResult]] = None
|
297
|
+
malicious_entity: Optional[GuardDetector[MaliciousEntityResult]] = None
|
298
|
+
pii_entity: Optional[GuardDetector[PiiEntityResult]] = None
|
299
|
+
profanity_and_toxicity: Optional[GuardDetector[object]] = None
|
300
|
+
prompt_injection: Optional[GuardDetector[PromptInjectionResult]] = None
|
301
|
+
secrets_detection: Optional[GuardDetector[SecretsEntityResult]] = None
|
302
|
+
selfharm: Optional[GuardDetector[object]] = None
|
303
|
+
sentiment: Optional[GuardDetector[object]] = None
|
304
|
+
topic: Optional[GuardDetector[TopicDetectionResult]] = None
|
303
305
|
|
304
306
|
|
305
307
|
class PromptMessage(APIResponseModel):
|
@@ -336,6 +338,121 @@ class TextGuardResult(PangeaResponseResult):
|
|
336
338
|
"""Whether or not the original input was transformed."""
|
337
339
|
|
338
340
|
|
341
|
+
class Tool(RootModel[str]):
|
342
|
+
root: Annotated[str, Field(min_length=1)]
|
343
|
+
"""Tool name"""
|
344
|
+
|
345
|
+
|
346
|
+
class McpTool(APIRequestModel):
|
347
|
+
server_name: Annotated[str, Field(min_length=1)]
|
348
|
+
"""MCP server name"""
|
349
|
+
|
350
|
+
tools: Annotated[list[Tool], Field(min_length=1)]
|
351
|
+
|
352
|
+
|
353
|
+
class ExtraInfo(BaseModel):
|
354
|
+
"""(AIDR) Logging schema."""
|
355
|
+
|
356
|
+
# Additional properties are allowed here.
|
357
|
+
model_config = ConfigDict(extra="allow")
|
358
|
+
|
359
|
+
app_name: Optional[str] = None
|
360
|
+
"""Name of source application/agent."""
|
361
|
+
|
362
|
+
app_group: Optional[str] = None
|
363
|
+
"""The group of source application/agent."""
|
364
|
+
|
365
|
+
app_version: Optional[str] = None
|
366
|
+
"""Version of the source application/agent."""
|
367
|
+
|
368
|
+
actor_name: Optional[str] = None
|
369
|
+
"""Name of subject actor/service account."""
|
370
|
+
|
371
|
+
actor_group: Optional[str] = None
|
372
|
+
"""The group of subject actor."""
|
373
|
+
|
374
|
+
source_region: Optional[str] = None
|
375
|
+
"""Geographic region or data center."""
|
376
|
+
|
377
|
+
sub_tenant: Optional[str] = None
|
378
|
+
"""Sub tenant of the user or organization"""
|
379
|
+
mcp_tools: Optional[Sequence[McpTool]] = None
|
380
|
+
|
381
|
+
"""Each item groups tools for a given MCP server."""
|
382
|
+
|
383
|
+
|
384
|
+
class AccessRuleResult(APIResponseModel):
|
385
|
+
"""
|
386
|
+
Details about the evaluation of a single rule, including whether it matched,
|
387
|
+
the action to take, the rule name, and optional debugging information.
|
388
|
+
"""
|
389
|
+
|
390
|
+
matched: bool
|
391
|
+
"""Whether this rule's logic evaluated to true for the input."""
|
392
|
+
|
393
|
+
action: str
|
394
|
+
"""
|
395
|
+
The action resulting from the rule evaluation. One of 'allowed', 'blocked',
|
396
|
+
or 'reported'.
|
397
|
+
"""
|
398
|
+
|
399
|
+
name: str
|
400
|
+
"""A human-readable name for the rule."""
|
401
|
+
|
402
|
+
logic: Optional[dict[str, Any]] = None
|
403
|
+
"""The JSON logic expression evaluated for this rule."""
|
404
|
+
|
405
|
+
attributes: Optional[dict[str, Any]] = None
|
406
|
+
"""The input attribute values that were available during rule evaluation."""
|
407
|
+
|
408
|
+
|
409
|
+
class GuardDetectors(APIResponseModel):
|
410
|
+
"""Result of the recipe analyzing and input prompt."""
|
411
|
+
|
412
|
+
code: Optional[GuardDetector[CodeDetectionResult]] = None
|
413
|
+
competitors: Optional[GuardDetector[object]] = None
|
414
|
+
confidential_and_pii_entity: Optional[GuardDetector[PiiEntityResult]] = None
|
415
|
+
custom_entity: Optional[GuardDetector[object]] = None
|
416
|
+
language: Optional[GuardDetector[LanguageDetectionResult]] = None
|
417
|
+
malicious_entity: Optional[GuardDetector[MaliciousEntityResult]] = None
|
418
|
+
malicious_prompt: Optional[GuardDetector[PromptInjectionResult]] = None
|
419
|
+
prompt_hardening: Optional[GuardDetector[object]] = None
|
420
|
+
secret_and_key_entity: Optional[GuardDetector[SecretsEntityResult]] = None
|
421
|
+
topic: Optional[GuardDetector[TopicDetectionResult]] = None
|
422
|
+
|
423
|
+
|
424
|
+
class GuardResult(PangeaResponseResult):
|
425
|
+
output: Optional[dict[str, Any]] = None
|
426
|
+
"""Updated structured prompt."""
|
427
|
+
|
428
|
+
blocked: Optional[bool] = None
|
429
|
+
"""Whether or not the prompt triggered a block detection."""
|
430
|
+
|
431
|
+
transformed: Optional[bool] = None
|
432
|
+
"""Whether or not the original input was transformed."""
|
433
|
+
|
434
|
+
recipe: Optional[str] = None
|
435
|
+
"""The Recipe that was used."""
|
436
|
+
|
437
|
+
detectors: GuardDetectors
|
438
|
+
"""Result of the recipe analyzing and input prompt."""
|
439
|
+
|
440
|
+
access_rules: Optional[dict[str, AccessRuleResult]] = None
|
441
|
+
"""Result of the recipe evaluating configured rules"""
|
442
|
+
|
443
|
+
fpe_context: Optional[str] = None
|
444
|
+
"""
|
445
|
+
If an FPE redaction method returned results, this will be the context passed
|
446
|
+
to unredact.
|
447
|
+
"""
|
448
|
+
|
449
|
+
input_token_count: Optional[float] = None
|
450
|
+
"""Number of tokens counted in the input"""
|
451
|
+
|
452
|
+
output_token_count: Optional[float] = None
|
453
|
+
"""Number of tokens counted in the output"""
|
454
|
+
|
455
|
+
|
339
456
|
class AIGuard(ServiceBase):
|
340
457
|
"""AI Guard service client.
|
341
458
|
|
@@ -514,6 +631,82 @@ class AIGuard(ServiceBase):
|
|
514
631
|
|
515
632
|
return response
|
516
633
|
|
634
|
+
def guard(
|
635
|
+
self,
|
636
|
+
input: Mapping[str, Any],
|
637
|
+
*,
|
638
|
+
recipe: str | None = None,
|
639
|
+
debug: bool | None = None,
|
640
|
+
overrides: Overrides | None = None,
|
641
|
+
app_id: str | None = None,
|
642
|
+
actor_id: str | None = None,
|
643
|
+
llm_provider: str | None = None,
|
644
|
+
model: str | None = None,
|
645
|
+
model_version: str | None = None,
|
646
|
+
request_token_count: int | None = None,
|
647
|
+
response_token_count: int | None = None,
|
648
|
+
source_ip: str | None = None,
|
649
|
+
source_location: str | None = None,
|
650
|
+
tenant_id: str | None = None,
|
651
|
+
event_type: Literal["input", "output", "tool_input", "tool_output", "tool_listing"] | None = None,
|
652
|
+
collector_instance_id: str | None = None,
|
653
|
+
extra_info: ExtraInfo | None = None,
|
654
|
+
count_tokens: bool | None = None,
|
655
|
+
) -> PangeaResponse[GuardResult]:
|
656
|
+
"""
|
657
|
+
Guard LLM input and output
|
658
|
+
|
659
|
+
Analyze and redact content to avoid manipulation of the model, addition
|
660
|
+
of malicious content, and other undesirable data transfers.
|
661
|
+
|
662
|
+
OperationId: ai_guard_post_v1_guard
|
663
|
+
|
664
|
+
Args:
|
665
|
+
input: 'messages' (required) contains Prompt content and role array
|
666
|
+
in JSON format. The `content` is the multimodal text or image
|
667
|
+
input that will be analyzed. Additional properties such as
|
668
|
+
'tools' may be provided for analysis.
|
669
|
+
recipe: Recipe key of a configuration of data types and settings defined in the Pangea User Console. It specifies the rules that are to be applied to the text, such as defang malicious URLs.
|
670
|
+
debug: Setting this value to true will provide a detailed analysis of the text data
|
671
|
+
app_name: Name of source application.
|
672
|
+
llm_provider: Underlying LLM. Example: 'OpenAI'.
|
673
|
+
model: Model used to perform the event. Example: 'gpt'.
|
674
|
+
model_version: Model version used to perform the event. Example: '3.5'.
|
675
|
+
request_token_count: Number of tokens in the request.
|
676
|
+
response_token_count: Number of tokens in the response.
|
677
|
+
source_ip: IP address of user or app or agent.
|
678
|
+
source_location: Location of user or app or agent.
|
679
|
+
tenant_id: For gateway-like integrations with multi-tenant support.
|
680
|
+
event_type: (AIDR) Event Type.
|
681
|
+
collector_instance_id: (AIDR) collector instance id.
|
682
|
+
extra_info: (AIDR) Logging schema.
|
683
|
+
count_tokens: Provide input and output token count.
|
684
|
+
"""
|
685
|
+
return self.request.post(
|
686
|
+
"v1/guard",
|
687
|
+
GuardResult,
|
688
|
+
data={
|
689
|
+
"input": input,
|
690
|
+
"recipe": recipe,
|
691
|
+
"debug": debug,
|
692
|
+
"overrides": overrides,
|
693
|
+
"app_id": app_id,
|
694
|
+
"actor_id": actor_id,
|
695
|
+
"llm_provider": llm_provider,
|
696
|
+
"model": model,
|
697
|
+
"model_version": model_version,
|
698
|
+
"request_token_count": request_token_count,
|
699
|
+
"response_token_count": response_token_count,
|
700
|
+
"source_ip": source_ip,
|
701
|
+
"source_location": source_location,
|
702
|
+
"tenant_id": tenant_id,
|
703
|
+
"event_type": event_type,
|
704
|
+
"collector_instance_id": collector_instance_id,
|
705
|
+
"extra_info": extra_info,
|
706
|
+
"count_tokens": count_tokens,
|
707
|
+
},
|
708
|
+
)
|
709
|
+
|
517
710
|
|
518
711
|
def get_relevant_content(
|
519
712
|
messages: Sequence[Message | McpToolsMessage],
|
@@ -1,7 +1,10 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING, Literal, Optional
|
3
|
+
from typing import TYPE_CHECKING, Annotated, Literal, Optional
|
4
4
|
|
5
|
+
from pydantic import Field
|
6
|
+
|
7
|
+
from pangea._typing import SequenceNotStr
|
5
8
|
from pangea.config import PangeaConfig
|
6
9
|
from pangea.response import APIRequestModel, APIResponseModel, PangeaResponse, PangeaResponseResult
|
7
10
|
from pangea.services.base import ServiceBase
|
@@ -33,19 +36,18 @@ class GuardResult(PangeaResponseResult):
|
|
33
36
|
detected: bool
|
34
37
|
"""Boolean response for if the prompt was considered malicious or not"""
|
35
38
|
|
39
|
+
analyzer: Optional[str] = None
|
40
|
+
|
36
41
|
type: Optional[Literal["direct", "indirect", ""]] = None
|
37
42
|
"""Type of analysis, either direct or indirect"""
|
38
43
|
|
39
|
-
|
40
|
-
"""Prompt Analyzers for identifying and rejecting properties of prompts"""
|
41
|
-
|
42
|
-
confidence: float
|
44
|
+
confidence: Annotated[Optional[float], Field(ge=0.0, le=1.0)] = None
|
43
45
|
"""Percent of confidence in the detection result, ranging from 0 to 1"""
|
44
46
|
|
45
47
|
info: Optional[str] = None
|
46
48
|
"""Extra information about the detection result"""
|
47
49
|
|
48
|
-
classifications: list[Classification]
|
50
|
+
classifications: Optional[list[Classification]] = None
|
49
51
|
"""List of classification results with labels and confidence scores"""
|
50
52
|
|
51
53
|
|
@@ -92,7 +94,7 @@ class PromptGuard(ServiceBase):
|
|
92
94
|
self,
|
93
95
|
messages: Iterable[Message],
|
94
96
|
*,
|
95
|
-
analyzers:
|
97
|
+
analyzers: SequenceNotStr[str] | None = None,
|
96
98
|
classify: bool | None = None,
|
97
99
|
) -> PangeaResponse[GuardResult]:
|
98
100
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "pangea-sdk"
|
3
|
-
version = "6.
|
3
|
+
version = "6.7.0"
|
4
4
|
description = "Pangea API SDK"
|
5
5
|
authors = [
|
6
6
|
{name = "Glenn Gallien", email = "glenn.gallien@pangea.cloud"}
|
@@ -15,10 +15,10 @@ classifiers = [
|
|
15
15
|
requires-python = ">=3.9.2,<4.0.0"
|
16
16
|
dependencies = [
|
17
17
|
"aiohttp (>=3.12.15,<4.0.0)",
|
18
|
-
"cryptography (>=45.0.
|
18
|
+
"cryptography (>=45.0.7,<46.0.0)",
|
19
19
|
"deprecated (>=1.2.18,<2.0.0)",
|
20
20
|
"google-crc32c (>=1.7.1,<2.0.0)",
|
21
|
-
"pydantic (>=2.11.
|
21
|
+
"pydantic (>=2.11.9,<3.0.0)",
|
22
22
|
"python-dateutil (>=2.9.0.post0,<3.0.0)",
|
23
23
|
"requests (>=2.32.5,<3.0.0)",
|
24
24
|
"requests-toolbelt (>=1.0.0,<2.0.0)",
|
@@ -32,15 +32,15 @@ repository = "https://github.com/pangeacyber/pangea-python"
|
|
32
32
|
[dependency-groups]
|
33
33
|
dev = [
|
34
34
|
"docstring-parser ==0.17.0",
|
35
|
-
"pytest-asyncio ==1.
|
35
|
+
"pytest-asyncio ==1.2.0",
|
36
36
|
"pytest_httpserver ==1.1.3",
|
37
37
|
"types-Deprecated ==1.2.15.20250304",
|
38
38
|
"types-python-dateutil ==2.9.0.20250822",
|
39
|
-
"types-requests ==2.32.4.
|
39
|
+
"types-requests ==2.32.4.20250913",
|
40
40
|
]
|
41
41
|
|
42
42
|
[build-system]
|
43
|
-
requires = ["uv_build==0.8.
|
43
|
+
requires = ["uv_build==0.8.17"]
|
44
44
|
build-backend = "uv_build"
|
45
45
|
|
46
46
|
[tool.mypy]
|
@@ -54,7 +54,7 @@ warn_unused_ignores = true
|
|
54
54
|
plugins = ['pydantic.mypy']
|
55
55
|
|
56
56
|
[tool.pydantic-mypy]
|
57
|
-
init_forbid_extra =
|
57
|
+
init_forbid_extra = false
|
58
58
|
init_typed = true
|
59
59
|
warn_required_dynamic_aliases = true
|
60
60
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|