aigp-strands 1.0.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.
@@ -0,0 +1,40 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+ .eggs/
9
+
10
+ # Node
11
+ node_modules/
12
+ dist/
13
+
14
+ # Go
15
+ bin/
16
+
17
+ # Rust
18
+ target/
19
+
20
+ # .NET
21
+ bin/
22
+ obj/
23
+
24
+ # Java
25
+ *.class
26
+ out/
27
+
28
+ # IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+
33
+ # OS
34
+ .DS_Store
35
+ Thumbs.db
36
+
37
+ # Secrets (never commit)
38
+ .env
39
+ *.pem
40
+ *.key
@@ -0,0 +1,8 @@
1
+ Metadata-Version: 2.4
2
+ Name: aigp-strands
3
+ Version: 1.0.0
4
+ Summary: AIGP governance adapter for Strands Agents SDK
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: aigp-agent-core>=1.0.0
7
+ Provides-Extra: otel
8
+ Requires-Dist: opentelemetry-api>=1.20; extra == 'otel'
@@ -0,0 +1,8 @@
1
+ """AIGP-Strands — Governance adapter for Strands Agents SDK."""
2
+
3
+ __version__ = "1.0.0"
4
+
5
+ from .handler import AigpCallbackHandler
6
+ from .governance import AigpGovernance
7
+
8
+ __all__ = ["AigpGovernance", "AigpCallbackHandler"]
@@ -0,0 +1,17 @@
1
+ """AigpGovernance — entry point for Strands agent governance."""
2
+
3
+ from aigp_agent_core import AgentGovernance
4
+ from .handler import AigpCallbackHandler
5
+
6
+
7
+ class AigpGovernance(AgentGovernance):
8
+ """Strands-specific governance wrapper.
9
+
10
+ Usage:
11
+ governance = AigpGovernance(gov_url=..., app_id=..., hmac_secret=...)
12
+ agent = Agent(model=..., callback_handler=governance.callback_handler())
13
+ """
14
+
15
+ def callback_handler(self) -> AigpCallbackHandler:
16
+ """Create a Strands callback handler wired to this governance instance."""
17
+ return AigpCallbackHandler(self)
@@ -0,0 +1,61 @@
1
+ """Strands Callback Handler — maps Strands lifecycle to AIGP governance."""
2
+
3
+ import asyncio
4
+ import logging
5
+ import time
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class AigpCallbackHandler:
11
+ """Strands SDK callback handler implementing AIGP governance.
12
+
13
+ Attach to any Strands Agent:
14
+ agent = Agent(model=..., callback_handler=handler)
15
+ """
16
+
17
+ def __init__(self, governance):
18
+ self._gov = governance
19
+ self._tool_start_times: dict[str, float] = {}
20
+
21
+ def on_agent_start(self, agent_name: str, model_id: str, prompt: str, **kwargs):
22
+ """Called when agent starts processing. Sends AIGP CHECK."""
23
+ user_id = kwargs.get("user_id", "")
24
+ self._gov.pre_invoke(agent_name, model_id, user_id)
25
+
26
+ def on_model_start(self, model_id: str, prompt: str, **kwargs):
27
+ """Called before each model invocation within a cycle."""
28
+ pass # Trace stage already handled by pre_invoke
29
+
30
+ def on_model_end(self, response: str, usage: dict = None, **kwargs):
31
+ """Called after model returns. Accumulates tokens."""
32
+ self._gov.on_model_call(usage=usage or {})
33
+
34
+ def on_tool_start(self, tool_name: str, params: dict = None, **kwargs):
35
+ """Called before tool execution."""
36
+ self._tool_start_times[tool_name] = time.time()
37
+
38
+ def on_tool_end(self, tool_name: str, result: str = "", **kwargs):
39
+ """Called after tool execution. Records tool span."""
40
+ start = self._tool_start_times.pop(tool_name, time.time())
41
+ duration_ms = int((time.time() - start) * 1000)
42
+ try:
43
+ asyncio.get_event_loop().run_until_complete(
44
+ self._gov.on_tool_call(tool_name, duration_ms=duration_ms, result=result)
45
+ )
46
+ except RuntimeError:
47
+ asyncio.run(self._gov.on_tool_call(tool_name, duration_ms=duration_ms, result=result))
48
+
49
+ def on_agent_end(self, result: str = "", **kwargs):
50
+ """Called when agent completes. Sends RECORD + TRACE + evidence."""
51
+ try:
52
+ asyncio.get_event_loop().run_until_complete(self._gov.post_invoke())
53
+ except RuntimeError:
54
+ asyncio.run(self._gov.post_invoke())
55
+
56
+ def on_agent_error(self, error: Exception, **kwargs):
57
+ """Called on agent error."""
58
+ try:
59
+ asyncio.get_event_loop().run_until_complete(self._gov.on_error(error))
60
+ except RuntimeError:
61
+ asyncio.run(self._gov.on_error(error))
@@ -0,0 +1,13 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "aigp-strands"
7
+ version = "1.0.0"
8
+ description = "AIGP governance adapter for Strands Agents SDK"
9
+ requires-python = ">=3.11"
10
+ dependencies = ["aigp-agent-core>=1.0.0"]
11
+
12
+ [project.optional-dependencies]
13
+ otel = ["opentelemetry-api>=1.20"]