agenttrustid 0.3.0__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.
@@ -0,0 +1,100 @@
1
+ """
2
+ AgentTrust SDK - Authentication, authorization, and runtime security for AI agents.
3
+
4
+ Quick Start:
5
+ from agenttrustid import AgentTrustClient
6
+
7
+ # Initialize with gateway URL and API key
8
+ client = AgentTrustClient(base_url="http://localhost:8080", api_key="sk_live_xxx")
9
+
10
+ # Create an agent
11
+ agent = client.agents.create(name="my-agent", framework="langchain")
12
+
13
+ # LangChain integration (pip install agenttrustid[langchain])
14
+ from agenttrustid.callback import AgentTrustCallbackHandler
15
+ handler = AgentTrustCallbackHandler(client, agent_id=agent.id)
16
+ agent_executor.invoke({"input": "..."}, config={"callbacks": [handler]})
17
+
18
+ # CrewAI integration
19
+ from agenttrustid.crewai_callback import AgentTrustCrewAIToolWrapper, agenttrust_protect_crew
20
+
21
+ # AutoGen integration
22
+ from agenttrustid.autogen_callback import AgentTrustAutoGenToolWrapper, agenttrust_wrap_tool
23
+
24
+ """
25
+
26
+ from .client import AgentTrustClient
27
+ from .models import (
28
+ Agent,
29
+ Token,
30
+ IntrospectionResult,
31
+ VerificationResult,
32
+ ActionCheckResult,
33
+ AgentCard,
34
+ A2ATask,
35
+ A2AMessageTask,
36
+ MCPServer,
37
+ Delegation,
38
+ Session,
39
+ ApprovalRequest,
40
+ FederationProvider,
41
+ FederationIntrospectionResult,
42
+ VerifyFederatedTokenResult,
43
+ SIEMDestination,
44
+ SIEMDeliveryRecord,
45
+ )
46
+ from .a2a import A2AAPI
47
+ from .agentcard import AgentCardsAPI
48
+ from .mcp_client import MCPAPI
49
+ from .delegation import DelegationsAPI
50
+ from .federation import FederationAPI
51
+ from .streaming import StreamingAPI
52
+ from .client import SessionsAPI, ApprovalsAPI
53
+ from .guard import AgentTrustGuard
54
+ from .exceptions import (
55
+ AgentTrustError,
56
+ AuthenticationError,
57
+ AuthorizationError,
58
+ TokenExpiredError,
59
+ AgentRevokedError,
60
+ NetworkError,
61
+ ValidationError,
62
+ )
63
+
64
+ __version__ = "0.3.0"
65
+ __all__ = [
66
+ "AgentTrustClient",
67
+ "AgentTrustGuard",
68
+ "Agent",
69
+ "Token",
70
+ "IntrospectionResult",
71
+ "VerificationResult",
72
+ "ActionCheckResult",
73
+ "AgentCard",
74
+ "A2ATask",
75
+ "A2AMessageTask",
76
+ "MCPServer",
77
+ "Delegation",
78
+ "Session",
79
+ "ApprovalRequest",
80
+ "FederationProvider",
81
+ "FederationIntrospectionResult",
82
+ "VerifyFederatedTokenResult",
83
+ "SIEMDestination",
84
+ "SIEMDeliveryRecord",
85
+ "A2AAPI",
86
+ "AgentCardsAPI",
87
+ "MCPAPI",
88
+ "DelegationsAPI",
89
+ "FederationAPI",
90
+ "StreamingAPI",
91
+ "SessionsAPI",
92
+ "ApprovalsAPI",
93
+ "AgentTrustError",
94
+ "AuthenticationError",
95
+ "AuthorizationError",
96
+ "TokenExpiredError",
97
+ "AgentRevokedError",
98
+ "NetworkError",
99
+ "ValidationError",
100
+ ]
agenttrustid/a2a.py ADDED
@@ -0,0 +1,158 @@
1
+ """AgentTrust SDK A2A (Agent-to-Agent) Task Management"""
2
+
3
+ import uuid
4
+ from typing import Dict, List, Optional
5
+
6
+ from .models import A2ATask, A2AMessageTask
7
+
8
+
9
+ class A2AAPI:
10
+ """A2A task management API.
11
+
12
+ Enables agent-to-agent communication through the A2A protocol.
13
+ Tasks are dispatched via JSON-RPC through the /a2a endpoint.
14
+
15
+ Example:
16
+ # Send a task from one agent to another
17
+ task = client.a2a.send_task(
18
+ source_agent_id="agent-123",
19
+ target_agent_id="agent-456",
20
+ message="Summarize the latest security report",
21
+ )
22
+
23
+ # Check task status
24
+ task = client.a2a.get_task(task.id)
25
+
26
+ # Cancel if needed
27
+ client.a2a.cancel_task(task.id)
28
+ """
29
+
30
+ def __init__(self, http_client):
31
+ self._http = http_client
32
+
33
+ def _jsonrpc_request(self, method: str, params: dict, path: str = "/a2a") -> dict:
34
+ """Send a JSON-RPC request to an A2A endpoint.
35
+
36
+ Args:
37
+ method: JSON-RPC method name (e.g., "tasks/send")
38
+ params: Method parameters
39
+ path: Endpoint to POST to. Defaults to the shared ``/a2a``
40
+ endpoint; ``message/send`` targets the per-agent endpoint
41
+ ``/a2a/agents/{agent_id}`` so the server resolves the actor
42
+ from the path.
43
+
44
+ Returns:
45
+ The "result" field from the JSON-RPC response
46
+ """
47
+ payload = {
48
+ "jsonrpc": "2.0",
49
+ "id": 1,
50
+ "method": method,
51
+ "params": params,
52
+ }
53
+ response = self._http.post(path, payload)
54
+ # JSON-RPC responses have the result nested under "result"
55
+ if "result" in response:
56
+ return response["result"]
57
+ return response
58
+
59
+ def send_task(
60
+ self,
61
+ source_agent_id: str,
62
+ target_agent_id: str,
63
+ message: str,
64
+ metadata: Optional[Dict] = None,
65
+ ) -> A2ATask:
66
+ """
67
+ Send a task from one agent to another.
68
+
69
+ Args:
70
+ source_agent_id: ID of the agent sending the task
71
+ target_agent_id: ID of the agent receiving the task
72
+ message: Task message/instruction for the target agent
73
+ metadata: Optional metadata to attach to the task
74
+
75
+ Returns:
76
+ A2ATask with the created task details
77
+ """
78
+ params = {
79
+ "source_agent_id": source_agent_id,
80
+ "target_agent_id": target_agent_id,
81
+ "message": message,
82
+ }
83
+ if metadata:
84
+ params["metadata"] = metadata
85
+
86
+ result = self._jsonrpc_request("tasks/send", params)
87
+ return A2ATask.from_dict(result)
88
+
89
+ def get_task(self, task_id: str) -> A2ATask:
90
+ """
91
+ Get the current status and details of a task.
92
+
93
+ Args:
94
+ task_id: ID of the task to retrieve
95
+
96
+ Returns:
97
+ A2ATask with current task state
98
+ """
99
+ result = self._jsonrpc_request("tasks/get", {"task_id": task_id})
100
+ return A2ATask.from_dict(result)
101
+
102
+ def cancel_task(self, task_id: str) -> A2ATask:
103
+ """
104
+ Cancel a pending or in-progress task.
105
+
106
+ Args:
107
+ task_id: ID of the task to cancel
108
+
109
+ Returns:
110
+ A2ATask with updated (cancelled) status
111
+ """
112
+ result = self._jsonrpc_request("tasks/cancel", {"task_id": task_id})
113
+ return A2ATask.from_dict(result)
114
+
115
+ def send_message(
116
+ self,
117
+ agent_id: str,
118
+ text: str,
119
+ message_id: Optional[str] = None,
120
+ task_id: Optional[str] = None,
121
+ ) -> A2AMessageTask:
122
+ """
123
+ Send a message to an agent using the A2A v1.0 ``message/send`` method.
124
+
125
+ Dispatches a JSON-RPC ``message/send`` call to the target agent's
126
+ per-agent endpoint ``/a2a/agents/{agent_id}`` (mirroring the other
127
+ SDKs) so the server resolves the actor from the path. The message
128
+ follows the v1.0 schema with a text part. A new ``messageId`` is
129
+ generated when one is not supplied. If ``task_id`` is given, the
130
+ message is attached to that existing task.
131
+
132
+ Args:
133
+ agent_id: ID of the target agent.
134
+ text: The text content of the message.
135
+ message_id: Optional client-supplied message ID (a UUID is
136
+ generated when omitted).
137
+ task_id: Optional existing task ID to continue.
138
+
139
+ Returns:
140
+ A2AMessageTask parsed from the v1.0 Task result
141
+ ``{id, contextId, status: {state, timestamp}, history?, artifacts?}``.
142
+ """
143
+ message: Dict = {
144
+ "role": "user",
145
+ "parts": [{"kind": "text", "text": text}],
146
+ "messageId": message_id or str(uuid.uuid4()),
147
+ }
148
+ if task_id:
149
+ message["taskId"] = task_id
150
+
151
+ # Post to the per-agent endpoint; the server authorizes message/send
152
+ # from the path agent, not a params field. Params carry only the
153
+ # message, matching the Go/TS/Java/Rust SDKs.
154
+ params = {"message": message}
155
+ result = self._jsonrpc_request(
156
+ "message/send", params, path=f"/a2a/agents/{agent_id}"
157
+ )
158
+ return A2AMessageTask.from_dict(result)
@@ -0,0 +1,87 @@
1
+ """AgentTrust SDK Agent Card Management"""
2
+
3
+ from typing import Optional
4
+
5
+ from .models import AgentCard
6
+
7
+
8
+ class AgentCardsAPI:
9
+ """Agent Card management API.
10
+
11
+ Agent Cards provide standardized metadata about an agent's identity,
12
+ capabilities, supported interfaces, and skills following the A2A
13
+ protocol v1.0. Cards are parsed into :class:`AgentCard`; use
14
+ ``card.primary_url`` and ``card.trust_score`` to read the endpoint and
15
+ ATI trust extension.
16
+
17
+ Example:
18
+ # Generate and publish a card
19
+ card = client.agent_cards.generate(agent_id="agent-123")
20
+ client.agent_cards.publish(agent_id="agent-123")
21
+
22
+ # Retrieve the public card (no auth required)
23
+ public_card = client.agent_cards.get_public(agent_id="agent-123")
24
+ """
25
+
26
+ def __init__(self, http_client):
27
+ self._http = http_client
28
+
29
+ def generate(self, agent_id: str) -> AgentCard:
30
+ """
31
+ Generate an Agent Card for the given agent.
32
+
33
+ Creates or regenerates the agent's card with current metadata,
34
+ capabilities, and security policy information.
35
+
36
+ Args:
37
+ agent_id: ID of the agent to generate a card for
38
+
39
+ Returns:
40
+ AgentCard with the generated card data
41
+ """
42
+ result = self._http.post(f"/api/v1/agents/{agent_id}/card")
43
+ return AgentCard.from_dict(result)
44
+
45
+ def get(self, agent_id: str) -> AgentCard:
46
+ """
47
+ Get the Agent Card for the given agent.
48
+
49
+ Args:
50
+ agent_id: ID of the agent
51
+
52
+ Returns:
53
+ AgentCard with current card data
54
+ """
55
+ result = self._http.get(f"/api/v1/agents/{agent_id}/card")
56
+ return AgentCard.from_dict(result)
57
+
58
+ def publish(self, agent_id: str) -> AgentCard:
59
+ """
60
+ Publish the agent's card, making it publicly discoverable.
61
+
62
+ Once published, the card is available at the well-known URL
63
+ and can be discovered by other agents via A2A protocol.
64
+
65
+ Args:
66
+ agent_id: ID of the agent
67
+
68
+ Returns:
69
+ AgentCard with updated publish status
70
+ """
71
+ result = self._http.put(f"/api/v1/agents/{agent_id}/card/publish")
72
+ return AgentCard.from_dict(result)
73
+
74
+ def get_public(self, agent_id: str) -> AgentCard:
75
+ """
76
+ Get the publicly published Agent Card (no authentication required).
77
+
78
+ This uses the well-known A2A discovery path.
79
+
80
+ Args:
81
+ agent_id: ID of the agent
82
+
83
+ Returns:
84
+ AgentCard with public card data
85
+ """
86
+ result = self._http.get(f"/a2a/agents/{agent_id}/agent.json")
87
+ return AgentCard.from_dict(result)