-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprecheck.py
More file actions
115 lines (100 loc) · 3.75 KB
/
Copy pathprecheck.py
File metadata and controls
115 lines (100 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# SPDX-License-Identifier: Elastic-2.0
# Copyright (c) 2026 GovernsAI. All rights reserved.
"""
Precheck data models for request validation and governance compliance.
"""
from dataclasses import dataclass
from typing import Dict, List, Optional, Any, Union
from enum import Enum
class Decision(Enum):
"""Decision types for precheck responses."""
ALLOW = "allow"
DENY = "deny"
# Backward-compatible alias; canonical blocking decision is "deny".
BLOCK = "deny"
CONFIRM = "confirm"
REDACT = "redact"
@dataclass
class PrecheckRequest:
"""Request model for prechecking AI operations."""
tool: str
scope: str
raw_text: str
payload: Dict[str, Any]
tags: List[str]
corr_id: Optional[str] = None
user_id: Optional[str] = None
policy_config: Optional[Dict[str, Any]] = None
tool_config: Optional[Dict[str, Any]] = None
budget_context: Optional[Dict[str, Any]] = None
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary for API requests."""
payload: Dict[str, Any] = {
"tool": self.tool,
"scope": self.scope,
"raw_text": self.raw_text,
"payload": self.payload,
"tags": self.tags,
"corr_id": self.corr_id,
"user_id": self.user_id,
"policy_config": self.policy_config,
"tool_config": self.tool_config,
"budget_context": self.budget_context,
}
return {key: value for key, value in payload.items() if value is not None}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "PrecheckRequest":
"""Create from dictionary."""
return cls(
tool=data["tool"],
scope=data["scope"],
raw_text=data.get("raw_text", data.get("rawText", "")),
payload=data.get("payload", {}),
tags=data.get("tags", []),
corr_id=data.get("corr_id", data.get("corrId")),
user_id=data.get("user_id", data.get("userId")),
policy_config=data.get("policy_config", data.get("policyConfig")),
tool_config=data.get("tool_config", data.get("toolConfig")),
budget_context=data.get("budget_context", data.get("budgetContext")),
)
@dataclass
class PrecheckResponse:
"""Response model for precheck operations."""
decision: Union[Decision, str]
reasons: List[str]
metadata: Optional[Dict[str, Any]] = None
requires_confirmation: bool = False
confirmation_url: Optional[str] = None
def __post_init__(self):
"""Convert string decision to Decision enum if needed."""
if isinstance(self.decision, str):
if self.decision == "block":
self.decision = "deny"
try:
self.decision = Decision(self.decision)
except ValueError:
# If not a valid enum value, keep as string
pass
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "PrecheckResponse":
"""Create from dictionary."""
return cls(
decision=data["decision"],
reasons=data.get("reasons", []),
metadata=data.get("metadata"),
requires_confirmation=data.get("requiresConfirmation", False),
confirmation_url=data.get("confirmationUrl"),
)
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary."""
return {
"decision": (
self.decision.value
if isinstance(self.decision, Decision)
else self.decision
),
"reasons": self.reasons,
"metadata": self.metadata,
"requiresConfirmation": self.requires_confirmation,
"confirmationUrl": self.confirmation_url,
}