maigp-client 5.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.
- maigp_client-5.0.0/.gitignore +45 -0
- maigp_client-5.0.0/Makefile +13 -0
- maigp_client-5.0.0/PKG-INFO +178 -0
- maigp_client-5.0.0/README.md +151 -0
- maigp_client-5.0.0/aigp_client/__init__.py +64 -0
- maigp_client-5.0.0/aigp_client/african_context.py +102 -0
- maigp_client-5.0.0/aigp_client/agent_client.py +619 -0
- maigp_client-5.0.0/aigp_client/anticipation.py +72 -0
- maigp_client-5.0.0/aigp_client/backoff.py +32 -0
- maigp_client-5.0.0/aigp_client/client.py +658 -0
- maigp_client-5.0.0/aigp_client/config.py +62 -0
- maigp_client-5.0.0/aigp_client/context.py +112 -0
- maigp_client-5.0.0/aigp_client/delegation.py +66 -0
- maigp_client-5.0.0/aigp_client/govern.py +25 -0
- maigp_client-5.0.0/aigp_client/japanese_context.py +83 -0
- maigp_client-5.0.0/aigp_client/logger.py +35 -0
- maigp_client-5.0.0/aigp_client/providers/__init__.py +10 -0
- maigp_client-5.0.0/aigp_client/providers/consent/__init__.py +6 -0
- maigp_client-5.0.0/aigp_client/providers/consent/consent_helper_base.py +31 -0
- maigp_client-5.0.0/aigp_client/providers/consent/default/__init__.py +0 -0
- maigp_client-5.0.0/aigp_client/providers/consent/default/passthrough_helper.py +13 -0
- maigp_client-5.0.0/aigp_client/providers/model/__init__.py +7 -0
- maigp_client-5.0.0/aigp_client/providers/model/azure_openai/__init__.py +0 -0
- maigp_client-5.0.0/aigp_client/providers/model/bedrock/__init__.py +0 -0
- maigp_client-5.0.0/aigp_client/providers/model/bedrock/bedrock_model_provider.py +75 -0
- maigp_client-5.0.0/aigp_client/providers/model/model_provider_base.py +38 -0
- maigp_client-5.0.0/aigp_client/providers/model/model_provider_factory.py +24 -0
- maigp_client-5.0.0/aigp_client/providers/model/vertex/__init__.py +0 -0
- maigp_client-5.0.0/aigp_client/providers/storage/__init__.py +5 -0
- maigp_client-5.0.0/aigp_client/providers/storage/local/__init__.py +5 -0
- maigp_client-5.0.0/aigp_client/providers/storage/local/local_storage_provider.py +54 -0
- maigp_client-5.0.0/aigp_client/providers/storage/s3/__init__.py +5 -0
- maigp_client-5.0.0/aigp_client/providers/storage/s3/s3_storage_provider.py +56 -0
- maigp_client-5.0.0/aigp_client/providers/storage/storage_provider_base.py +32 -0
- maigp_client-5.0.0/aigp_client/providers/transport/__init__.py +6 -0
- maigp_client-5.0.0/aigp_client/providers/transport/httpx/__init__.py +0 -0
- maigp_client-5.0.0/aigp_client/providers/transport/httpx/httpx_transport.py +29 -0
- maigp_client-5.0.0/aigp_client/providers/transport/transport_base.py +24 -0
- maigp_client-5.0.0/aigp_client/regulatory.py +81 -0
- maigp_client-5.0.0/aigp_client/schemas/__init__.py +5 -0
- maigp_client-5.0.0/aigp_client/schemas/geo.py +106 -0
- maigp_client-5.0.0/aigp_client/session.py +28 -0
- maigp_client-5.0.0/aigp_client/streaming.py +71 -0
- maigp_client-5.0.0/aigp_client/tokens.py +46 -0
- maigp_client-5.0.0/aigp_client/tools.py +50 -0
- maigp_client-5.0.0/aigp_client/trace_builder.py +140 -0
- maigp_client-5.0.0/pyproject.toml +36 -0
- maigp_client-5.0.0/tests/test_agent_client_orchestration.py +346 -0
- maigp_client-5.0.0/tests/test_agent_client_safety.py +249 -0
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
.kiro/
|
|
32
|
+
*.swp
|
|
33
|
+
|
|
34
|
+
# OS
|
|
35
|
+
.DS_Store
|
|
36
|
+
Thumbs.db
|
|
37
|
+
|
|
38
|
+
# Secrets (never commit)
|
|
39
|
+
.env
|
|
40
|
+
*.pem
|
|
41
|
+
*.key
|
|
42
|
+
*.pdf
|
|
43
|
+
BACKLOG/
|
|
44
|
+
patent/
|
|
45
|
+
docs/.archive/
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: maigp-client
|
|
3
|
+
Version: 5.0.0
|
|
4
|
+
Summary: MAIGP (Mediated AI Governance Protocol) client — consent-based runtime AI governance
|
|
5
|
+
Project-URL: Homepage, https://github.com/owner-spec/aigp-protocol
|
|
6
|
+
Project-URL: Documentation, https://github.com/owner-spec/aigp-protocol/tree/main/specification
|
|
7
|
+
Project-URL: Repository, https://github.com/owner-spec/aigp-protocol
|
|
8
|
+
Author-email: Evan Erwee <evan@erwee.com>
|
|
9
|
+
License: Proprietary
|
|
10
|
+
Keywords: ai,aigp,bedrock,governance,llm,maigp,mediated,protocol
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: Other/Proprietary License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Security
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: httpx>=0.25.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
25
|
+
Requires-Dist: respx; extra == 'dev'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# aigp-client
|
|
29
|
+
|
|
30
|
+
Universal AI Governance Protocol (AIGP) client v4.0 — consent-based runtime AI governance with jurisdictional enforcement.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install aigp-client
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from aigp_client import AigpClient
|
|
42
|
+
|
|
43
|
+
client = AigpClient("https://your-gov-server.com", "my-app", "hmac-secret")
|
|
44
|
+
|
|
45
|
+
# Declare governance context (once at startup)
|
|
46
|
+
client.declare_universal_context({"active": True, "principles": "ALL"})
|
|
47
|
+
|
|
48
|
+
# Every AI call: CHECK → invoke → RECORD
|
|
49
|
+
decision = await client.check("chat", "claude-4")
|
|
50
|
+
# ... invoke your model ...
|
|
51
|
+
await client.record(use_case="chat", model_id="claude-4", input_tokens=500, output_tokens=200, duration_ms=1200)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## One-Line Governance
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from aigp_client import govern
|
|
58
|
+
|
|
59
|
+
aigp = govern("https://gov-server.com", "my-app", "secret")
|
|
60
|
+
result = await aigp.wrap(my_ai_function) # CHECK + RECORD automatic
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Jurisdictional Governance (v4.0)
|
|
64
|
+
|
|
65
|
+
Declare which legal frameworks govern your AI system:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from aigp_client import (
|
|
69
|
+
AigpClient, HumanitarianContext, RegulatoryContext,
|
|
70
|
+
AfricanContext, JapaneseContext,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
client = AigpClient("https://gov.example.com", "my-app", "secret")
|
|
74
|
+
|
|
75
|
+
# Universal baseline (RFC-031) — all apps should declare this
|
|
76
|
+
client.declare_universal_context({"active": True, "principles": "ALL", "accountability_required": True})
|
|
77
|
+
|
|
78
|
+
# EU AI Act (RFC-028)
|
|
79
|
+
client.declare_regulatory_context(RegulatoryContext(
|
|
80
|
+
active=True, framework="EU_AI_ACT", risk_classification="HIGH_RISK",
|
|
81
|
+
deployer_jurisdiction="DE",
|
|
82
|
+
))
|
|
83
|
+
|
|
84
|
+
# Japan AI Promotion Act (RFC-030)
|
|
85
|
+
client.declare_japanese_context(JapaneseContext(
|
|
86
|
+
active=True, governance_framework="JAPAN_AI_PROMOTION_ACT",
|
|
87
|
+
sector="HEALTHCARE", innovation_priority=True,
|
|
88
|
+
))
|
|
89
|
+
|
|
90
|
+
# AU Continental AI Strategy (RFC-029)
|
|
91
|
+
client.declare_african_context(AfricanContext(
|
|
92
|
+
active=True, governance_framework="AU_CONTINENTAL_AI_STRATEGY",
|
|
93
|
+
member_state="KE", ubuntu_principle=True,
|
|
94
|
+
))
|
|
95
|
+
|
|
96
|
+
# IHL — conflict zones (RFC-027)
|
|
97
|
+
client.declare_humanitarian_context(HumanitarianContext(
|
|
98
|
+
active=True, legal_regime="IHL_GCIV", conflict_classification="NIAC",
|
|
99
|
+
operating_authority="ICRC",
|
|
100
|
+
))
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
All subsequent CHECK requests are evaluated against declared contexts. Priority: IHL → EU → AU → Japan → Universal.
|
|
104
|
+
|
|
105
|
+
## User Feedback (RFC-026)
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
await client.feedback(request_id="req-123", session_id="ses-abc",
|
|
109
|
+
rating="thumbs_up", pseudonym_id="user-hash")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Multi-Agent Delegation
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from aigp_client import SessionContext, DelegationToken
|
|
116
|
+
|
|
117
|
+
session = SessionContext(user_id="coordinator@company.com")
|
|
118
|
+
child = session.child(scope=["search_only"])
|
|
119
|
+
|
|
120
|
+
token = DelegationToken(issuer="coordinator", delegate="worker",
|
|
121
|
+
allowed_models=["claude-4"], max_tokens=10000)
|
|
122
|
+
encoded = token.encode("shared-secret")
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Token Tracking
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from aigp_client import TokenAccumulator
|
|
129
|
+
|
|
130
|
+
tokens = TokenAccumulator()
|
|
131
|
+
tokens.add_from_usage({"prompt_tokens": 500, "completion_tokens": 200}) # OpenAI
|
|
132
|
+
tokens.add_from_usage({"inputTokens": 300, "outputTokens": 150}) # Bedrock
|
|
133
|
+
print(f"Total: {tokens.total_input} in, {tokens.total_output} out")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Full Lifecycle Trace
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from aigp_client import TraceBuilder
|
|
140
|
+
|
|
141
|
+
tb = TraceBuilder(request_id="req-1")
|
|
142
|
+
tb.start(1); tb.end(1, attributes={"user_id": "user@co.com"}) # Identity
|
|
143
|
+
tb.start(3); tb.end(3, attributes={"decision": "ALLOW"}) # CHECK
|
|
144
|
+
tb.start(9); tb.end(9, attributes={"model": "claude-4"}) # Invoke
|
|
145
|
+
tb.add_tool_span("search_docs", duration_ms=45) # Tool
|
|
146
|
+
tb.start(14); tb.end(14) # RECORD
|
|
147
|
+
spans, summary = tb.build()
|
|
148
|
+
await client.trace(trace_id=tb.trace_id, spans=spans, summary=summary)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Tool Governance
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from aigp_client import ToolGovernance
|
|
155
|
+
|
|
156
|
+
tg = ToolGovernance(client=client)
|
|
157
|
+
decision = await tg.check_tool("execute_sql", params={"query": "SELECT *"})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Modes
|
|
161
|
+
|
|
162
|
+
| Mode | Behavior | When server unreachable |
|
|
163
|
+
|------|----------|:-:|
|
|
164
|
+
| `REPORT` | Log all, allow all | Allow (fail-open) |
|
|
165
|
+
| `REPORT-TRACE` | Log + stage-level spans | Allow (fail-open) |
|
|
166
|
+
| `ENFORCE` | Check policies, block violations | Deny (fail-closed) |
|
|
167
|
+
|
|
168
|
+
## Supported Languages
|
|
169
|
+
|
|
170
|
+
| Python | TypeScript | Go | Java | C# | Rust | Ruby | Swift |
|
|
171
|
+
|:------:|:----------:|:--:|:----:|:--:|:----:|:----:|:-----:|
|
|
172
|
+
| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
173
|
+
|
|
174
|
+
All 8 SDKs have: `declareHumanitarianContext`, `declareRegulatoryContext`, `declareAfricanContext`, `declareJapaneseContext`, `declareUniversalContext`.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
Proprietary — © 2025-2026 Evan Erwee. All rights reserved.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# aigp-client
|
|
2
|
+
|
|
3
|
+
Universal AI Governance Protocol (AIGP) client v4.0 — consent-based runtime AI governance with jurisdictional enforcement.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install aigp-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from aigp_client import AigpClient
|
|
15
|
+
|
|
16
|
+
client = AigpClient("https://your-gov-server.com", "my-app", "hmac-secret")
|
|
17
|
+
|
|
18
|
+
# Declare governance context (once at startup)
|
|
19
|
+
client.declare_universal_context({"active": True, "principles": "ALL"})
|
|
20
|
+
|
|
21
|
+
# Every AI call: CHECK → invoke → RECORD
|
|
22
|
+
decision = await client.check("chat", "claude-4")
|
|
23
|
+
# ... invoke your model ...
|
|
24
|
+
await client.record(use_case="chat", model_id="claude-4", input_tokens=500, output_tokens=200, duration_ms=1200)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## One-Line Governance
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from aigp_client import govern
|
|
31
|
+
|
|
32
|
+
aigp = govern("https://gov-server.com", "my-app", "secret")
|
|
33
|
+
result = await aigp.wrap(my_ai_function) # CHECK + RECORD automatic
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Jurisdictional Governance (v4.0)
|
|
37
|
+
|
|
38
|
+
Declare which legal frameworks govern your AI system:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from aigp_client import (
|
|
42
|
+
AigpClient, HumanitarianContext, RegulatoryContext,
|
|
43
|
+
AfricanContext, JapaneseContext,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
client = AigpClient("https://gov.example.com", "my-app", "secret")
|
|
47
|
+
|
|
48
|
+
# Universal baseline (RFC-031) — all apps should declare this
|
|
49
|
+
client.declare_universal_context({"active": True, "principles": "ALL", "accountability_required": True})
|
|
50
|
+
|
|
51
|
+
# EU AI Act (RFC-028)
|
|
52
|
+
client.declare_regulatory_context(RegulatoryContext(
|
|
53
|
+
active=True, framework="EU_AI_ACT", risk_classification="HIGH_RISK",
|
|
54
|
+
deployer_jurisdiction="DE",
|
|
55
|
+
))
|
|
56
|
+
|
|
57
|
+
# Japan AI Promotion Act (RFC-030)
|
|
58
|
+
client.declare_japanese_context(JapaneseContext(
|
|
59
|
+
active=True, governance_framework="JAPAN_AI_PROMOTION_ACT",
|
|
60
|
+
sector="HEALTHCARE", innovation_priority=True,
|
|
61
|
+
))
|
|
62
|
+
|
|
63
|
+
# AU Continental AI Strategy (RFC-029)
|
|
64
|
+
client.declare_african_context(AfricanContext(
|
|
65
|
+
active=True, governance_framework="AU_CONTINENTAL_AI_STRATEGY",
|
|
66
|
+
member_state="KE", ubuntu_principle=True,
|
|
67
|
+
))
|
|
68
|
+
|
|
69
|
+
# IHL — conflict zones (RFC-027)
|
|
70
|
+
client.declare_humanitarian_context(HumanitarianContext(
|
|
71
|
+
active=True, legal_regime="IHL_GCIV", conflict_classification="NIAC",
|
|
72
|
+
operating_authority="ICRC",
|
|
73
|
+
))
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
All subsequent CHECK requests are evaluated against declared contexts. Priority: IHL → EU → AU → Japan → Universal.
|
|
77
|
+
|
|
78
|
+
## User Feedback (RFC-026)
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
await client.feedback(request_id="req-123", session_id="ses-abc",
|
|
82
|
+
rating="thumbs_up", pseudonym_id="user-hash")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Multi-Agent Delegation
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from aigp_client import SessionContext, DelegationToken
|
|
89
|
+
|
|
90
|
+
session = SessionContext(user_id="coordinator@company.com")
|
|
91
|
+
child = session.child(scope=["search_only"])
|
|
92
|
+
|
|
93
|
+
token = DelegationToken(issuer="coordinator", delegate="worker",
|
|
94
|
+
allowed_models=["claude-4"], max_tokens=10000)
|
|
95
|
+
encoded = token.encode("shared-secret")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Token Tracking
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from aigp_client import TokenAccumulator
|
|
102
|
+
|
|
103
|
+
tokens = TokenAccumulator()
|
|
104
|
+
tokens.add_from_usage({"prompt_tokens": 500, "completion_tokens": 200}) # OpenAI
|
|
105
|
+
tokens.add_from_usage({"inputTokens": 300, "outputTokens": 150}) # Bedrock
|
|
106
|
+
print(f"Total: {tokens.total_input} in, {tokens.total_output} out")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Full Lifecycle Trace
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from aigp_client import TraceBuilder
|
|
113
|
+
|
|
114
|
+
tb = TraceBuilder(request_id="req-1")
|
|
115
|
+
tb.start(1); tb.end(1, attributes={"user_id": "user@co.com"}) # Identity
|
|
116
|
+
tb.start(3); tb.end(3, attributes={"decision": "ALLOW"}) # CHECK
|
|
117
|
+
tb.start(9); tb.end(9, attributes={"model": "claude-4"}) # Invoke
|
|
118
|
+
tb.add_tool_span("search_docs", duration_ms=45) # Tool
|
|
119
|
+
tb.start(14); tb.end(14) # RECORD
|
|
120
|
+
spans, summary = tb.build()
|
|
121
|
+
await client.trace(trace_id=tb.trace_id, spans=spans, summary=summary)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Tool Governance
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from aigp_client import ToolGovernance
|
|
128
|
+
|
|
129
|
+
tg = ToolGovernance(client=client)
|
|
130
|
+
decision = await tg.check_tool("execute_sql", params={"query": "SELECT *"})
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Modes
|
|
134
|
+
|
|
135
|
+
| Mode | Behavior | When server unreachable |
|
|
136
|
+
|------|----------|:-:|
|
|
137
|
+
| `REPORT` | Log all, allow all | Allow (fail-open) |
|
|
138
|
+
| `REPORT-TRACE` | Log + stage-level spans | Allow (fail-open) |
|
|
139
|
+
| `ENFORCE` | Check policies, block violations | Deny (fail-closed) |
|
|
140
|
+
|
|
141
|
+
## Supported Languages
|
|
142
|
+
|
|
143
|
+
| Python | TypeScript | Go | Java | C# | Rust | Ruby | Swift |
|
|
144
|
+
|:------:|:----------:|:--:|:----:|:--:|:----:|:----:|:-----:|
|
|
145
|
+
| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
146
|
+
|
|
147
|
+
All 8 SDKs have: `declareHumanitarianContext`, `declareRegulatoryContext`, `declareAfricanContext`, `declareJapaneseContext`, `declareUniversalContext`.
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
Proprietary — © 2025-2026 Evan Erwee. All rights reserved.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""AIGP Client v4.0 — Universal AI Governance Protocol client.
|
|
2
|
+
|
|
3
|
+
Provides:
|
|
4
|
+
- Protocol transport (CHECK/RECORD/TRACE)
|
|
5
|
+
- Session context for multi-agent linking
|
|
6
|
+
- Token accumulation for streaming/multi-cycle
|
|
7
|
+
- Tool governance (per-tool CHECK)
|
|
8
|
+
- Delegation tokens (agent-to-agent scoping)
|
|
9
|
+
- Stream accumulator (periodic RECORD during streaming)
|
|
10
|
+
- Rate-limit backoff
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
__version__ = "4.0.0"
|
|
14
|
+
|
|
15
|
+
# Core protocol
|
|
16
|
+
from .client import AigpClient, GovernanceDecision
|
|
17
|
+
from .trace_builder import TraceBuilder, STAGE_NAMES
|
|
18
|
+
from .context import HumanitarianContext
|
|
19
|
+
from .regulatory import RegulatoryContext
|
|
20
|
+
from .african_context import AfricanContext
|
|
21
|
+
from .japanese_context import JapaneseContext
|
|
22
|
+
|
|
23
|
+
# v3.0+ — Agent support
|
|
24
|
+
from .session import SessionContext
|
|
25
|
+
from .tokens import TokenAccumulator
|
|
26
|
+
from .tools import ToolGovernance
|
|
27
|
+
from .delegation import DelegationToken
|
|
28
|
+
from .streaming import StreamAccumulator
|
|
29
|
+
from .backoff import retry_on_rate_limit
|
|
30
|
+
|
|
31
|
+
# One-line governance wrapper
|
|
32
|
+
from .govern import govern
|
|
33
|
+
|
|
34
|
+
# RFC-032: Anticipation
|
|
35
|
+
from .anticipation import AnticipationBuilder, Criterion
|
|
36
|
+
|
|
37
|
+
# Provider-based config
|
|
38
|
+
from .config import ClientConfig, ClientComponents
|
|
39
|
+
from .providers.model import ModelProviderBase
|
|
40
|
+
from .providers.transport import TransportProviderBase
|
|
41
|
+
from .providers.consent import ConsentHelperBase, TokenMap
|
|
42
|
+
from .schemas import GeoContext
|
|
43
|
+
|
|
44
|
+
__all__ = [
|
|
45
|
+
# Core
|
|
46
|
+
"AigpClient", "GovernanceDecision",
|
|
47
|
+
"TraceBuilder", "STAGE_NAMES",
|
|
48
|
+
"HumanitarianContext",
|
|
49
|
+
"RegulatoryContext",
|
|
50
|
+
"AfricanContext",
|
|
51
|
+
"JapaneseContext",
|
|
52
|
+
# v3.0+ Agent support
|
|
53
|
+
"SessionContext", "TokenAccumulator", "ToolGovernance",
|
|
54
|
+
"DelegationToken", "StreamAccumulator", "retry_on_rate_limit",
|
|
55
|
+
# Config/Providers
|
|
56
|
+
"ClientConfig", "ClientComponents",
|
|
57
|
+
"ModelProviderBase", "TransportProviderBase",
|
|
58
|
+
"ConsentHelperBase", "TokenMap",
|
|
59
|
+
"GeoContext",
|
|
60
|
+
# Governance wrapper
|
|
61
|
+
"govern",
|
|
62
|
+
# RFC-032: Anticipation
|
|
63
|
+
"AnticipationBuilder", "Criterion",
|
|
64
|
+
]
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""RFC-029: African Context — typed context for AU Continental AI Strategy alignment.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
from aigp_client.african_context import AfricanContext
|
|
5
|
+
|
|
6
|
+
ctx = AfricanContext(
|
|
7
|
+
active=True,
|
|
8
|
+
governance_framework="AU_CONTINENTAL_AI_STRATEGY",
|
|
9
|
+
member_state="KE",
|
|
10
|
+
rec="EAC",
|
|
11
|
+
)
|
|
12
|
+
client.declare_african_context(ctx)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from dataclasses import dataclass, field
|
|
16
|
+
|
|
17
|
+
VALID_FRAMEWORKS = {"AU_CONTINENTAL_AI_STRATEGY"}
|
|
18
|
+
VALID_RECS = {"EAC", "ECOWAS", "SADC", "COMESA", "AMU", "IGAD", "ECCAS", "CEN-SAD"}
|
|
19
|
+
VALID_SECTORS = {"HEALTH", "AGRICULTURE", "EDUCATION", "PUBLIC_SERVICES", "FINANCE", "ENVIRONMENT"}
|
|
20
|
+
VALID_BENEFICIARIES = {"YOUTH", "WOMEN", "RURAL_COMMUNITIES", "DISABLED", "ELDERLY"}
|
|
21
|
+
VALID_CROSS_BORDER = {"MALABO_CONVENTION", "AU_DATA_POLICY_FRAMEWORK"}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class AfricanContext:
|
|
26
|
+
"""AU Continental AI Strategy context declaration per RFC-029."""
|
|
27
|
+
|
|
28
|
+
active: bool
|
|
29
|
+
governance_framework: str
|
|
30
|
+
member_state: str
|
|
31
|
+
rec: str = ""
|
|
32
|
+
local_first: bool = False
|
|
33
|
+
ubuntu_principle: bool = False
|
|
34
|
+
priority_sector: str = ""
|
|
35
|
+
beneficiary_groups: list[str] = field(default_factory=list)
|
|
36
|
+
language_context: list[str] = field(default_factory=list)
|
|
37
|
+
data_sovereignty: dict = field(default_factory=dict)
|
|
38
|
+
cultural_sensitivity: dict = field(default_factory=dict)
|
|
39
|
+
|
|
40
|
+
def __post_init__(self):
|
|
41
|
+
self.validate()
|
|
42
|
+
|
|
43
|
+
def validate(self) -> None:
|
|
44
|
+
"""Raise ValueError if context is invalid."""
|
|
45
|
+
if self.governance_framework not in VALID_FRAMEWORKS:
|
|
46
|
+
raise ValueError(f"Invalid governance_framework: {self.governance_framework}. Must be one of {VALID_FRAMEWORKS}")
|
|
47
|
+
if not self.member_state or len(self.member_state) != 2:
|
|
48
|
+
raise ValueError("member_state must be a 2-letter ISO 3166-1 alpha-2 code")
|
|
49
|
+
if self.rec and self.rec not in VALID_RECS:
|
|
50
|
+
raise ValueError(f"Invalid rec: {self.rec}. Must be one of {VALID_RECS}")
|
|
51
|
+
if self.priority_sector and self.priority_sector not in VALID_SECTORS:
|
|
52
|
+
raise ValueError(f"Invalid priority_sector: {self.priority_sector}. Must be one of {VALID_SECTORS}")
|
|
53
|
+
for bg in self.beneficiary_groups:
|
|
54
|
+
if bg not in VALID_BENEFICIARIES:
|
|
55
|
+
raise ValueError(f"Invalid beneficiary_group: {bg}. Must be one of {VALID_BENEFICIARIES}")
|
|
56
|
+
if self.data_sovereignty:
|
|
57
|
+
cbf = self.data_sovereignty.get("cross_border_framework")
|
|
58
|
+
if cbf and cbf not in VALID_CROSS_BORDER:
|
|
59
|
+
raise ValueError(f"Invalid cross_border_framework: {cbf}. Must be one of {VALID_CROSS_BORDER}")
|
|
60
|
+
|
|
61
|
+
def to_dict(self) -> dict:
|
|
62
|
+
"""Serialize for protocol transmission."""
|
|
63
|
+
d = {
|
|
64
|
+
"active": self.active,
|
|
65
|
+
"governance_framework": self.governance_framework,
|
|
66
|
+
"member_state": self.member_state,
|
|
67
|
+
"local_first": self.local_first,
|
|
68
|
+
"ubuntu_principle": self.ubuntu_principle,
|
|
69
|
+
}
|
|
70
|
+
if self.rec:
|
|
71
|
+
d["rec"] = self.rec
|
|
72
|
+
if self.priority_sector:
|
|
73
|
+
d["priority_sector"] = self.priority_sector
|
|
74
|
+
if self.beneficiary_groups:
|
|
75
|
+
d["beneficiary_groups"] = self.beneficiary_groups
|
|
76
|
+
if self.language_context:
|
|
77
|
+
d["language_context"] = self.language_context
|
|
78
|
+
if self.data_sovereignty:
|
|
79
|
+
d["data_sovereignty"] = self.data_sovereignty
|
|
80
|
+
if self.cultural_sensitivity:
|
|
81
|
+
d["cultural_sensitivity"] = self.cultural_sensitivity
|
|
82
|
+
return d
|
|
83
|
+
|
|
84
|
+
def merge(self, request_level: dict) -> "AfricanContext":
|
|
85
|
+
"""Merge request-level context. Escalation only — cannot downgrade."""
|
|
86
|
+
if not request_level:
|
|
87
|
+
return self
|
|
88
|
+
if request_level.get("active") is False:
|
|
89
|
+
request_level["active"] = True
|
|
90
|
+
return AfricanContext(
|
|
91
|
+
active=True,
|
|
92
|
+
governance_framework=request_level.get("governance_framework", self.governance_framework),
|
|
93
|
+
member_state=request_level.get("member_state", self.member_state),
|
|
94
|
+
rec=request_level.get("rec", self.rec),
|
|
95
|
+
local_first=request_level.get("local_first", self.local_first),
|
|
96
|
+
ubuntu_principle=request_level.get("ubuntu_principle", self.ubuntu_principle),
|
|
97
|
+
priority_sector=request_level.get("priority_sector", self.priority_sector),
|
|
98
|
+
beneficiary_groups=list(set(self.beneficiary_groups + request_level.get("beneficiary_groups", []))),
|
|
99
|
+
language_context=list(set(self.language_context + request_level.get("language_context", []))),
|
|
100
|
+
data_sovereignty=request_level.get("data_sovereignty", self.data_sovereignty),
|
|
101
|
+
cultural_sensitivity=request_level.get("cultural_sensitivity", self.cultural_sensitivity),
|
|
102
|
+
)
|