trustmodel 3.3.0__tar.gz → 3.3.2__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.
- {trustmodel-3.3.0 → trustmodel-3.3.2}/PKG-INFO +1 -1
- {trustmodel-3.3.0 → trustmodel-3.3.2}/pyproject.toml +1 -1
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/__init__.py +6 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/agentcert.py +83 -5
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/agentic.py +13 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/exceptions.py +32 -1
- {trustmodel-3.3.0 → trustmodel-3.3.2}/.gitignore +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/LICENSE +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/README.md +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/cli.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/client.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/compat.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/__init__.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/_runtime_transport.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/batch_jobs.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/config.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/credits.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/evaluations.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/frameworks.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/galileo.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/guardrails.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/mcp_scanner.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/endpoints/models.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/__init__.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/agentcert.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/agentic.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/batch_job.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/credits.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/evaluation.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/frameworks.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/galileo.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/guardrails.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/mcp_scanner.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/models.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/models/oauth.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/oauth/__init__.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/oauth/auth.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/oauth/scopes.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/telemetry/__init__.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/telemetry/_constants.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/telemetry/_instrumentors.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/telemetry/auto_init.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/utils/__init__.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/utils/validation.py +0 -0
- {trustmodel-3.3.0 → trustmodel-3.3.2}/src/trustmodel/utils/version.py +0 -0
|
@@ -16,10 +16,13 @@ except ImportError:
|
|
|
16
16
|
|
|
17
17
|
from .client import TrustModelClient
|
|
18
18
|
from .exceptions import (
|
|
19
|
+
AgentCertInvalidRunTypeError,
|
|
20
|
+
AgentCertRunNotCompletedError,
|
|
19
21
|
APIError,
|
|
20
22
|
AuthenticationError,
|
|
21
23
|
ConnectionValidationError,
|
|
22
24
|
EdgeUnreachableError,
|
|
25
|
+
EvaluationNotFoundError,
|
|
23
26
|
InsufficientCreditsError,
|
|
24
27
|
RateLimitError,
|
|
25
28
|
TrustModelError,
|
|
@@ -60,6 +63,9 @@ __all__ = [
|
|
|
60
63
|
"InsufficientCreditsError",
|
|
61
64
|
"ConnectionValidationError",
|
|
62
65
|
"EdgeUnreachableError",
|
|
66
|
+
"EvaluationNotFoundError",
|
|
67
|
+
"AgentCertInvalidRunTypeError",
|
|
68
|
+
"AgentCertRunNotCompletedError",
|
|
63
69
|
"Decision",
|
|
64
70
|
"OAuthClientCredentials",
|
|
65
71
|
"PKCEAuthorizationCode",
|
|
@@ -18,9 +18,14 @@ Contract: agentcert/docs/api-v0.md. Ticket: TRUS-1228 (EPIC TRUS-1219).
|
|
|
18
18
|
|
|
19
19
|
from __future__ import annotations
|
|
20
20
|
|
|
21
|
-
from typing import TYPE_CHECKING, Optional, Tuple
|
|
22
|
-
|
|
23
|
-
from ..exceptions import
|
|
21
|
+
from typing import TYPE_CHECKING, Any, Optional, Tuple
|
|
22
|
+
|
|
23
|
+
from ..exceptions import (
|
|
24
|
+
AgentCertInvalidRunTypeError,
|
|
25
|
+
AgentCertRunNotCompletedError,
|
|
26
|
+
APIError,
|
|
27
|
+
EvaluationNotFoundError,
|
|
28
|
+
)
|
|
24
29
|
from ..models.agentcert import AgentCertificate, AgentCertVerification
|
|
25
30
|
|
|
26
31
|
if TYPE_CHECKING:
|
|
@@ -37,6 +42,51 @@ _VERIFY_PATH = "/v1/verify/{agent}/"
|
|
|
37
42
|
# a legitimate "not found" answer, surfaced as a result, not an exception.
|
|
38
43
|
_NOT_FOUND_STATUS = 404
|
|
39
44
|
|
|
45
|
+
# TRUS-1643 — mint 400 error codes → typed exception class. Two body
|
|
46
|
+
# shapes exist in the wild:
|
|
47
|
+
# 1. Legacy handler-emitted: ``{"error": "...", "code": "issuance_failed"}``
|
|
48
|
+
# (from ``AgentCertView`` catching ``IssuanceError``).
|
|
49
|
+
# 2. DRF ValidationError-emitted (TRUS-1643): field-level shape —
|
|
50
|
+
# ``{"evaluation_run_id": ["..."], "code": ["invalid_run_type_for_agentcert"]}``.
|
|
51
|
+
# The gateway ``code`` is either a plain string or a single-element list;
|
|
52
|
+
# ``_extract_error_code`` normalises to a plain string so callers get a
|
|
53
|
+
# stable typed exception either way.
|
|
54
|
+
_MINT_ERROR_CODE_TO_EXC = {
|
|
55
|
+
"invalid_run_type_for_agentcert": AgentCertInvalidRunTypeError,
|
|
56
|
+
"run_not_completed_for_agentcert": AgentCertRunNotCompletedError,
|
|
57
|
+
"evaluation_run_not_found": EvaluationNotFoundError,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _extract_error_code(exc: APIError) -> Optional[str]:
|
|
62
|
+
"""Return the machine-parseable ``code`` from a mint 400 body, or None.
|
|
63
|
+
|
|
64
|
+
Handles both the legacy flat ``code`` string and the DRF-serializer
|
|
65
|
+
flattened ``code`` list. Falls back to ``exc.response`` when the
|
|
66
|
+
client-level ``exc.error_code`` didn't preserve the list shape.
|
|
67
|
+
|
|
68
|
+
Edge cases that intentionally return ``None`` (caller must fall
|
|
69
|
+
through to raising the plain ``APIError``):
|
|
70
|
+
* empty string ``""`` — degenerate legacy body
|
|
71
|
+
* ``[""]`` — degenerate DRF body
|
|
72
|
+
* ``[]`` / non-string first element — malformed body
|
|
73
|
+
None of the ``_MINT_ERROR_CODE_TO_EXC`` keys are empty, so a ``""``
|
|
74
|
+
lookup misses the routing table and falls through anyway.
|
|
75
|
+
"""
|
|
76
|
+
# ``raw`` is typed ``Any`` because the two source shapes disagree:
|
|
77
|
+
# ``APIError.error_code`` is declared ``Optional[str]`` (legacy handler
|
|
78
|
+
# shape), but the DRF ValidationError body arrives with ``code`` as a
|
|
79
|
+
# single-element list. Both survive here — the isinstance checks below
|
|
80
|
+
# narrow at runtime.
|
|
81
|
+
raw: Any = exc.error_code
|
|
82
|
+
if raw is None and isinstance(exc.response, dict):
|
|
83
|
+
raw = exc.response.get("code")
|
|
84
|
+
if isinstance(raw, str) and raw:
|
|
85
|
+
return raw
|
|
86
|
+
if isinstance(raw, list) and raw and isinstance(raw[0], str):
|
|
87
|
+
return raw[0]
|
|
88
|
+
return None
|
|
89
|
+
|
|
40
90
|
|
|
41
91
|
class AgentCertEndpoint:
|
|
42
92
|
"""Issue, verify, and certify AgentCerts. Mounted as ``client.agentcert``."""
|
|
@@ -58,6 +108,12 @@ class AgentCertEndpoint:
|
|
|
58
108
|
Calls ``POST /sdk/v1/agentcert/issue/`` (the API-key-authed wrapper).
|
|
59
109
|
The org is derived from the API key server-side.
|
|
60
110
|
|
|
111
|
+
**Eligible run types (TRUS-1643):** the eval run must be an
|
|
112
|
+
``agent-evaluation-run`` or ``agentic-trace-run`` in ``completed``
|
|
113
|
+
status. Standard model evals, leaderboard runs, data-scan runs, and
|
|
114
|
+
RAG corpus runs are rejected with a stable 400 error code so callers
|
|
115
|
+
can route the user back to picking a compatible run.
|
|
116
|
+
|
|
61
117
|
Args:
|
|
62
118
|
ans_name: Agent Naming Service binding (e.g. ``helpbot.cisco.com``).
|
|
63
119
|
evaluation_run_id: Source eval run id (must belong to the org).
|
|
@@ -71,7 +127,14 @@ class AgentCertEndpoint:
|
|
|
71
127
|
|
|
72
128
|
Raises:
|
|
73
129
|
ValueError: ``ans_name`` or ``evaluation_run_id`` missing.
|
|
74
|
-
|
|
130
|
+
AgentCertInvalidRunTypeError: run's ``run_type`` isn't eligible
|
|
131
|
+
(TRUS-1643 — see the note above). Subclass of :class:`APIError`.
|
|
132
|
+
AgentCertRunNotCompletedError: run exists but hasn't reached
|
|
133
|
+
``status=completed`` yet. Subclass of :class:`APIError`.
|
|
134
|
+
EvaluationNotFoundError: run id isn't visible in the caller's
|
|
135
|
+
org (or doesn't exist). Subclass of :class:`APIError`.
|
|
136
|
+
APIError: any other non-2xx (e.g. 400 issuance_failed,
|
|
137
|
+
500 internal_issuance_error, 429).
|
|
75
138
|
"""
|
|
76
139
|
if not ans_name:
|
|
77
140
|
raise ValueError("agentcert.issue(): `ans_name` is required")
|
|
@@ -86,7 +149,22 @@ class AgentCertEndpoint:
|
|
|
86
149
|
if validity_days is not None:
|
|
87
150
|
data["validity_days"] = validity_days
|
|
88
151
|
|
|
89
|
-
|
|
152
|
+
try:
|
|
153
|
+
response = self._client.post(_ISSUE_PATH, data=data)
|
|
154
|
+
except APIError as exc:
|
|
155
|
+
code = _extract_error_code(exc)
|
|
156
|
+
# ``exc_class`` (was ``typed`` — shadowed the ``typing`` module
|
|
157
|
+
# name and read poorly at a glance). None-safe: unknown / empty
|
|
158
|
+
# codes miss the routing table and fall through to ``raise``.
|
|
159
|
+
exc_class = _MINT_ERROR_CODE_TO_EXC.get(code or "")
|
|
160
|
+
if exc_class is not None:
|
|
161
|
+
raise exc_class(
|
|
162
|
+
exc.message,
|
|
163
|
+
status_code=exc.status_code,
|
|
164
|
+
response=exc.response,
|
|
165
|
+
error_code=code,
|
|
166
|
+
) from exc
|
|
167
|
+
raise
|
|
90
168
|
return AgentCertificate(**response)
|
|
91
169
|
|
|
92
170
|
def verify(self, agent: str) -> AgentCertVerification:
|
|
@@ -115,6 +115,7 @@ class AgenticEndpoint:
|
|
|
115
115
|
goal_achieved: Optional[bool] = None,
|
|
116
116
|
frameworks: Optional[List[str]] = None,
|
|
117
117
|
control_ids: Optional[List[str]] = None,
|
|
118
|
+
governed_agent: Optional[str] = None,
|
|
118
119
|
) -> AgenticEvaluation:
|
|
119
120
|
"""
|
|
120
121
|
Evaluate an agent execution trace.
|
|
@@ -136,6 +137,13 @@ class AgenticEndpoint:
|
|
|
136
137
|
control_ids: Optional list of control IDs to scope the compliance
|
|
137
138
|
evaluation. Defaults server-side to all controls of the
|
|
138
139
|
selected frameworks.
|
|
140
|
+
governed_agent: Optional GovernedAgent slug OR UUID to bind this
|
|
141
|
+
run to (TRUS-1640). When supplied, the resulting
|
|
142
|
+
``ReportEvaluationRun`` is stamped with the FK so the agent's
|
|
143
|
+
badge / TrustScore history picks up this run. Must belong to
|
|
144
|
+
the caller's organization or the server returns HTTP 400
|
|
145
|
+
``governed_agent_not_found``. When omitted, the run lands
|
|
146
|
+
standalone (pre-TRUS-1640 behavior).
|
|
139
147
|
|
|
140
148
|
Returns:
|
|
141
149
|
Evaluation creation response with run ID and status.
|
|
@@ -227,6 +235,11 @@ class AgenticEndpoint:
|
|
|
227
235
|
eval_data["frameworks"] = frameworks
|
|
228
236
|
if control_ids:
|
|
229
237
|
eval_data["control_ids"] = control_ids
|
|
238
|
+
# TRUS-1640 — SDK peer of aurora-gateway PR #512. The BE resolves the
|
|
239
|
+
# supplied slug/UUID to a GovernedAgent and stamps the FK on create;
|
|
240
|
+
# omit when None so pre-1640 behavior (standalone runs) is preserved.
|
|
241
|
+
if governed_agent:
|
|
242
|
+
eval_data["governed_agent"] = governed_agent
|
|
230
243
|
|
|
231
244
|
response = self._client.post("/sdk/v1/agentic/evaluate/", data=eval_data)
|
|
232
245
|
|
|
@@ -71,7 +71,38 @@ class ModelNotFoundError(APIError):
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
class EvaluationNotFoundError(APIError):
|
|
74
|
-
"""Raised when a requested evaluation is not found.
|
|
74
|
+
"""Raised when a requested evaluation is not found.
|
|
75
|
+
|
|
76
|
+
TRUS-1643: also raised by ``client.agentcert.issue()`` when the mint
|
|
77
|
+
endpoint returns 400 with ``code=evaluation_run_not_found`` (i.e. the
|
|
78
|
+
run id exists globally but not in the caller's org).
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class AgentCertInvalidRunTypeError(APIError):
|
|
85
|
+
"""Raised when ``client.agentcert.issue()`` targets a run whose ``run_type``
|
|
86
|
+
is not certifiable as an agent (TRUS-1643).
|
|
87
|
+
|
|
88
|
+
Only ``agent-evaluation-run`` and ``agentic-trace-run`` are accepted by
|
|
89
|
+
the mint endpoint; ``standard-run`` / ``leaderboard-run`` /
|
|
90
|
+
``data-scan-run`` / ``rag-corpus-run`` all raise this error. Callers
|
|
91
|
+
should catch this to surface a "pick an Agent Evaluation run"
|
|
92
|
+
message rather than a generic 400.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class AgentCertRunNotCompletedError(APIError):
|
|
99
|
+
"""Raised when ``client.agentcert.issue()`` targets an eval run that has
|
|
100
|
+
not reached ``status=completed`` yet (TRUS-1643).
|
|
101
|
+
|
|
102
|
+
The mint endpoint requires a terminal-successful run so the score
|
|
103
|
+
snapshot is stable. Callers should wait for the run to complete (or
|
|
104
|
+
poll) before retrying.
|
|
105
|
+
"""
|
|
75
106
|
|
|
76
107
|
pass
|
|
77
108
|
|
|
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
|