nees-gp-sdk 0.1.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,3 @@
1
+ include README.md
2
+ include LICENSE
3
+ recursive-include nees_gp_sdk *.py py.typed
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: nees-gp-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for NEES GP — AI Governance Operating System
5
+ Home-page: https://github.com/NEES-Anna
6
+ Author: Nainacore Emotional Tech
7
+ Author-email: anna@nainacore.com
8
+ Project-URL: Documentation, https://nees-gp.onrender.com/docs
9
+ Project-URL: Source, https://github.com/NEES-Anna/NEES_GP_SDK
10
+ Project-URL: Tracker, https://github.com/NEES-Anna/NEES_GP_SDK/issues
11
+ Keywords: ai governance llm safety nees naina
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ Requires-Dist: requests>=2.28.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0; extra == "dev"
27
+ Requires-Dist: pytest-mock>=3.10; extra == "dev"
28
+ Requires-Dist: responses>=0.23; extra == "dev"
29
+ Dynamic: author
30
+ Dynamic: author-email
31
+ Dynamic: classifier
32
+ Dynamic: description
33
+ Dynamic: description-content-type
34
+ Dynamic: home-page
35
+ Dynamic: keywords
36
+ Dynamic: project-url
37
+ Dynamic: provides-extra
38
+ Dynamic: requires-dist
39
+ Dynamic: requires-python
40
+ Dynamic: summary
41
+
42
+ # NEES GP SDK
43
+
44
+ > AI Governance Operating System (AGOS) — control AI behavior across sessions, not just outputs.
45
+
46
+ ---
47
+
48
+ ## 🚀 What is NEES GP?
49
+
50
+ NEES GP is an **AI Governance Operating System** that manages AI behavior across time.
51
+
52
+ Unlike traditional AI safety tools that filter single outputs, NEES GP introduces:
53
+
54
+ * 🧠 **Intent-aware reasoning**
55
+ * 🔁 **Session-level governance**
56
+ * 🛡️ **Policy enforcement before generation**
57
+ * 📊 **Structured response metadata**
58
+
59
+ ---
60
+
61
+ ## 📦 Installation
62
+
63
+ ```bash
64
+ pip install nees-gp-sdk
65
+ ```
66
+
67
+ ---
68
+
69
+ ## ⚡ Quickstart (3 lines)
70
+
71
+ ```python
72
+ from nees_gp_sdk import Client
73
+
74
+ client = Client(api_key="your-api-key")
75
+
76
+ res = client.chat("Mujhe kuch samajh nahi aa raha life mein")
77
+
78
+ print(res.text)
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 🧠 Response Structure
84
+
85
+ Every response includes both **AI output + governance metadata**:
86
+
87
+ ```python
88
+ print(res.text) # AI response
89
+ print(res.intent) # e.g. "confusion"
90
+ print(res.framework) # e.g. "confusion_direction"
91
+ print(res.urgency) # "low" | "medium" | "high"
92
+ print(res.governance_clean) # True / False
93
+ ```
94
+
95
+ ---
96
+
97
+ ## 🎯 Why NEES GP?
98
+
99
+ Traditional AI:
100
+
101
+ * Input → Output filter
102
+
103
+ NEES GP:
104
+
105
+ * Input → Policy → Governance → Response → Session continuity
106
+
107
+ 👉 This enables **stateful AI control across conversations**
108
+
109
+ ---
110
+
111
+ ## 🔧 Configuration
112
+
113
+ ```python
114
+ client = Client(
115
+ api_key="your-api-key",
116
+ base_url="https://nees-gp.onrender.com",
117
+ timeout=30
118
+ )
119
+ ```
120
+
121
+ ---
122
+
123
+ ## ⚠️ Error Handling
124
+
125
+ ```python
126
+ from nees_gp_sdk.exceptions import NEESError
127
+
128
+ try:
129
+ res = client.chat("Hello")
130
+ except NEESError as e:
131
+ print("Error:", str(e))
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 🛡️ Security & Privacy
137
+
138
+ * API keys are never stored in the SDK
139
+ * No local data persistence beyond session context
140
+ * Governance decisions happen server-side
141
+
142
+ ---
143
+
144
+ ## 🧪 Example Use Cases
145
+
146
+ * AI copilots with behavioral control
147
+ * Emotion-aware assistants
148
+ * Enterprise AI governance layer
149
+ * Multi-agent coordination systems
150
+
151
+ ---
152
+
153
+ ## 🌐 Vision
154
+
155
+ NEES GP defines a new category:
156
+
157
+ > **AI Governance Operating System (AGOS)**
158
+
159
+ A system that governs AI behavior across time, not just at the point of output.
160
+
161
+ ---
162
+
163
+ ## 🤝 Contributing
164
+
165
+ Contributions, feedback, and ideas are welcome.
166
+
167
+ ---
168
+
169
+ ## 📄 License
170
+
171
+ MIT License
172
+
173
+ ---
174
+
175
+ ## 👤 Author
176
+
177
+ Built by Nainacore Emotional Tech
178
+ Founder: Piyush P. Jambhulkar - ANNA
@@ -0,0 +1,137 @@
1
+ # NEES GP SDK
2
+
3
+ > AI Governance Operating System (AGOS) — control AI behavior across sessions, not just outputs.
4
+
5
+ ---
6
+
7
+ ## 🚀 What is NEES GP?
8
+
9
+ NEES GP is an **AI Governance Operating System** that manages AI behavior across time.
10
+
11
+ Unlike traditional AI safety tools that filter single outputs, NEES GP introduces:
12
+
13
+ * 🧠 **Intent-aware reasoning**
14
+ * 🔁 **Session-level governance**
15
+ * 🛡️ **Policy enforcement before generation**
16
+ * 📊 **Structured response metadata**
17
+
18
+ ---
19
+
20
+ ## 📦 Installation
21
+
22
+ ```bash
23
+ pip install nees-gp-sdk
24
+ ```
25
+
26
+ ---
27
+
28
+ ## ⚡ Quickstart (3 lines)
29
+
30
+ ```python
31
+ from nees_gp_sdk import Client
32
+
33
+ client = Client(api_key="your-api-key")
34
+
35
+ res = client.chat("Mujhe kuch samajh nahi aa raha life mein")
36
+
37
+ print(res.text)
38
+ ```
39
+
40
+ ---
41
+
42
+ ## 🧠 Response Structure
43
+
44
+ Every response includes both **AI output + governance metadata**:
45
+
46
+ ```python
47
+ print(res.text) # AI response
48
+ print(res.intent) # e.g. "confusion"
49
+ print(res.framework) # e.g. "confusion_direction"
50
+ print(res.urgency) # "low" | "medium" | "high"
51
+ print(res.governance_clean) # True / False
52
+ ```
53
+
54
+ ---
55
+
56
+ ## 🎯 Why NEES GP?
57
+
58
+ Traditional AI:
59
+
60
+ * Input → Output filter
61
+
62
+ NEES GP:
63
+
64
+ * Input → Policy → Governance → Response → Session continuity
65
+
66
+ 👉 This enables **stateful AI control across conversations**
67
+
68
+ ---
69
+
70
+ ## 🔧 Configuration
71
+
72
+ ```python
73
+ client = Client(
74
+ api_key="your-api-key",
75
+ base_url="https://nees-gp.onrender.com",
76
+ timeout=30
77
+ )
78
+ ```
79
+
80
+ ---
81
+
82
+ ## ⚠️ Error Handling
83
+
84
+ ```python
85
+ from nees_gp_sdk.exceptions import NEESError
86
+
87
+ try:
88
+ res = client.chat("Hello")
89
+ except NEESError as e:
90
+ print("Error:", str(e))
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 🛡️ Security & Privacy
96
+
97
+ * API keys are never stored in the SDK
98
+ * No local data persistence beyond session context
99
+ * Governance decisions happen server-side
100
+
101
+ ---
102
+
103
+ ## 🧪 Example Use Cases
104
+
105
+ * AI copilots with behavioral control
106
+ * Emotion-aware assistants
107
+ * Enterprise AI governance layer
108
+ * Multi-agent coordination systems
109
+
110
+ ---
111
+
112
+ ## 🌐 Vision
113
+
114
+ NEES GP defines a new category:
115
+
116
+ > **AI Governance Operating System (AGOS)**
117
+
118
+ A system that governs AI behavior across time, not just at the point of output.
119
+
120
+ ---
121
+
122
+ ## 🤝 Contributing
123
+
124
+ Contributions, feedback, and ideas are welcome.
125
+
126
+ ---
127
+
128
+ ## 📄 License
129
+
130
+ MIT License
131
+
132
+ ---
133
+
134
+ ## 👤 Author
135
+
136
+ Built by Nainacore Emotional Tech
137
+ Founder: Piyush P. Jambhulkar - ANNA
@@ -0,0 +1,57 @@
1
+ """
2
+ nees_gp — NEES GP Python SDK
3
+ =============================
4
+ AI Governance Operating System SDK.
5
+
6
+ Quickstart:
7
+ from nees_gp import Client
8
+
9
+ client = Client(api_key="your-key")
10
+ response = client.chat("Mujhe kuch samajh nahi aa raha")
11
+ print(response.text)
12
+ print(response.intent) # "confusion"
13
+ print(response.governance_clean) # True
14
+
15
+ Or set NEES_API_KEY in your environment and call Client() with no arguments.
16
+ """
17
+
18
+ from .client import Client
19
+ from .exceptions import (
20
+ AuthError,
21
+ GovernanceError,
22
+ NEESAPIError,
23
+ NEESError,
24
+ RateLimitError,
25
+ TimeoutError,
26
+ ValidationError,
27
+ )
28
+ from .models import (
29
+ ChatResponse,
30
+ DriftReport,
31
+ HealthResponse,
32
+ LatencyInfo,
33
+ ProposalResponse,
34
+ )
35
+
36
+ __version__ = "0.1.0"
37
+ __author__ = "Nainacore Emotional Tech"
38
+ __all__ = [
39
+ # Client
40
+ "Client",
41
+ # Models
42
+ "ChatResponse",
43
+ "DriftReport",
44
+ "HealthResponse",
45
+ "LatencyInfo",
46
+ "ProposalResponse",
47
+ # Exceptions
48
+ "NEESError",
49
+ "AuthError",
50
+ "TimeoutError",
51
+ "RateLimitError",
52
+ "GovernanceError",
53
+ "ValidationError",
54
+ "NEESAPIError",
55
+ # Meta
56
+ "__version__",
57
+ ]
@@ -0,0 +1,277 @@
1
+ """
2
+ =========================================
3
+ The single class developers interact with.
4
+
5
+ Quickstart
6
+ ──────────
7
+ from nees_gp import Client
8
+
9
+ client = Client(api_key="your-key")
10
+ response = client.chat("Mujhe kuch samajh nahi aa raha")
11
+ print(response.text)
12
+ print(response.intent) # "confusion"
13
+ print(response.urgency) # "medium"
14
+ print(response.governance_clean) # True
15
+
16
+ Context manager
17
+ ───────────────
18
+ with Client(api_key="your-key") as client:
19
+ response = client.chat("Help me decide")
20
+ print(response.text)
21
+
22
+ Environment variable shortcut
23
+ ──────────────────────────────
24
+ export NEES_API_KEY="your-key"
25
+
26
+ from nees_gp import Client
27
+ client = Client() # reads NEES_API_KEY automatically
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import logging
33
+ from typing import Any, Optional
34
+
35
+ from .config import SDKConfig
36
+ from .exceptions import NEESError
37
+ from .models import (
38
+ ChatResponse, DriftReport, HealthResponse,
39
+ ProposalResponse,
40
+ )
41
+ from .session import Session
42
+ from .transport import Transport
43
+ from .utils import resolve_api_key
44
+
45
+ logger = logging.getLogger("nees_gp_sdk.client")
46
+
47
+
48
+ class Client:
49
+ """
50
+ NEES GP SDK client.
51
+
52
+ Parameters
53
+ ──────────
54
+ api_key API key (Bearer token). Falls back to NEES_API_KEY env var.
55
+ base_url NEES GP server URL. Default: https://nees-gp.onrender.com
56
+ timeout HTTP timeout in seconds. Default: 30
57
+ max_retries Retries on transient errors. Default: 2
58
+ authority_state Governance authority state A | B | C. Default: B
59
+ session_id Resume a known session by ID. Default: auto-generated UUID.
60
+ verify_ssl Verify SSL certificates. Default: True.
61
+
62
+ All methods raise subclasses of NEESError on failure.
63
+ """
64
+
65
+ def __init__(
66
+ self,
67
+ api_key: Optional[str] = None,
68
+ base_url: str = "https://nees-gp.onrender.com",
69
+ timeout: float = 30,
70
+ max_retries: int = 2,
71
+ authority_state: str = "B",
72
+ session_id: Optional[str] = None,
73
+ verify_ssl: bool = True,
74
+ ) -> None:
75
+ resolved_key = resolve_api_key(api_key)
76
+ self._config = SDKConfig(
77
+ api_key=resolved_key,
78
+ base_url=base_url,
79
+ timeout=timeout,
80
+ max_retries=max_retries,
81
+ authority_state=authority_state,
82
+ verify_ssl=verify_ssl,
83
+ )
84
+ self._transport = Transport(self._config)
85
+ self._session = Session(session_id=session_id)
86
+ logger.debug("Client initialised | base_url=%s session=%s", base_url, self._session)
87
+
88
+ # ─────────────────────────────────────────────────────────────────────────
89
+ # Core interface
90
+ # ─────────────────────────────────────────────────────────────────────────
91
+
92
+ def chat(
93
+ self,
94
+ message: str,
95
+ history: Optional[list[dict[str, str]]] = None,
96
+ session_id: Optional[str] = None,
97
+ ) -> ChatResponse:
98
+ """
99
+ Send a message through the NEES GP governed chat pipeline.
100
+
101
+ The client automatically maintains conversation history across
102
+ calls — you do not need to pass history manually for typical use.
103
+ Pass `history` explicitly only to inject external context.
104
+
105
+ Args:
106
+ message User message text (max 2000 characters).
107
+ history Optional explicit history override.
108
+ List of {"role": "user"|"assistant", "content": "..."}.
109
+ If None, the session's accumulated history is used.
110
+ session_id Override the session ID for this request only.
111
+
112
+ Returns:
113
+ ChatResponse with text, governance metadata, and trace_id.
114
+
115
+ Raises:
116
+ AuthError — invalid API key
117
+ TimeoutError — request exceeded timeout
118
+ GovernanceError — server pipeline not initialised
119
+ ValidationError — bad request payload
120
+ NEESAPIError — other server error
121
+ """
122
+ payload: dict[str, Any] = {
123
+ "message": message,
124
+ "history": history if history is not None else self._session.history_as_dicts(),
125
+ "session_id": session_id or self._session.session_id,
126
+ }
127
+ raw = self._transport.post("/v1/proxy/chat", json=payload)
128
+ resp = ChatResponse.from_dict(raw)
129
+
130
+ # Record the exchange in session history
131
+ self._session.record(message, resp.text)
132
+ logger.debug("chat: intent=%s urgency=%s clean=%s", resp.intent, resp.urgency, resp.governance_clean)
133
+ return resp
134
+
135
+ # ─────────────────────────────────────────────────────────────────────────
136
+ # Governance pipeline operations
137
+ # ─────────────────────────────────────────────────────────────────────────
138
+
139
+ def propose(
140
+ self,
141
+ name: str,
142
+ category: str,
143
+ payload: Optional[dict[str, Any]] = None,
144
+ principal: Optional[str] = None,
145
+ ) -> ProposalResponse:
146
+ """
147
+ Create a governance proposal via POST /propose.
148
+ Evaluates the action through G1–G7 gates without executing it.
149
+
150
+ Args:
151
+ name Human-readable action label.
152
+ category ActionCategory: READ | WRITE | EXTERNAL_CALL |
153
+ MEMORY_OP | DELEGATE | SYSTEM_CONFIG |
154
+ IRREVERSIBLE | SAFETY_CHANGE
155
+ payload Arbitrary action parameters dict.
156
+ principal Optional principal identifier.
157
+
158
+ Returns:
159
+ ProposalResponse with verdict, risk_level, and admissibility detail.
160
+ """
161
+ body: dict[str, Any] = {
162
+ "name": name,
163
+ "category": category.upper(),
164
+ "payload": payload or {},
165
+ }
166
+ if principal:
167
+ body["principal"] = principal
168
+ raw = self._transport.post("/propose", json=body)
169
+ return ProposalResponse.from_dict(raw)
170
+
171
+ # ─────────────────────────────────────────────────────────────────────────
172
+ # Monitoring
173
+ # ─────────────────────────────────────────────────────────────────────────
174
+
175
+ def health(self) -> HealthResponse:
176
+ """
177
+ Check NEES GP server liveness via GET /health.
178
+
179
+ Returns:
180
+ HealthResponse with status, uptime, authority_state.
181
+
182
+ Raises:
183
+ GovernanceError — server is unhealthy (503)
184
+ """
185
+ raw = self._transport.get("/health")
186
+ return HealthResponse.from_dict(raw)
187
+
188
+ def drift(self) -> DriftReport:
189
+ """
190
+ Get the current drift report via GET /trajectory.
191
+
192
+ Returns:
193
+ DriftReport with status, anomaly_score, drift_magnitude.
194
+ """
195
+ raw = self._transport.get("/trajectory")
196
+ return DriftReport.from_dict(raw)
197
+
198
+ def ledger(self, n: int = 20) -> list[dict[str, Any]]:
199
+ """
200
+ Fetch the last N audit entries from the governance ledger.
201
+
202
+ Args:
203
+ n Number of entries to return (max 200).
204
+
205
+ Returns:
206
+ List of raw ledger entry dicts.
207
+ """
208
+ raw = self._transport.get("/ledger", params={"n": min(n, 200)})
209
+ return raw.get("entries", [])
210
+
211
+ def policies(self) -> list[dict[str, Any]]:
212
+ """
213
+ List all currently loaded YAML governance policies.
214
+
215
+ Returns:
216
+ List of policy summary dicts.
217
+ """
218
+ raw = self._transport.get("/policies")
219
+ return raw.get("rules", [])
220
+
221
+ # ─────────────────────────────────────────────────────────────────────────
222
+ # Session management
223
+ # ─────────────────────────────────────────────────────────────────────────
224
+
225
+ def reset_session(self) -> str:
226
+ """
227
+ Clear conversation history and generate a new session_id.
228
+ Returns the new session_id.
229
+ """
230
+ self._session.reset()
231
+ logger.debug("Session reset: new id=%s", self._session.session_id)
232
+ return self._session.session_id
233
+
234
+ def resume_session(
235
+ self,
236
+ session_id: str,
237
+ history: Optional[list[dict[str, str]]] = None,
238
+ ) -> None:
239
+ """
240
+ Resume a previously known session.
241
+
242
+ Args:
243
+ session_id The session_id to resume.
244
+ history Optional history to restore. If None, starts empty.
245
+ """
246
+ self._session.seed(session_id, history)
247
+ logger.debug("Session resumed: id=%s turns=%d", session_id, self._session.turn_count // 2)
248
+
249
+ @property
250
+ def session_id(self) -> str:
251
+ """Current session identifier."""
252
+ return self._session.session_id
253
+
254
+ @property
255
+ def history(self) -> list[dict[str, str]]:
256
+ """Current conversation history as a list of dicts."""
257
+ return self._session.history_as_dicts()
258
+
259
+ # ─────────────────────────────────────────────────────────────────────────
260
+ # Context manager support
261
+ # ─────────────────────────────────────────────────────────────────────────
262
+
263
+ def __enter__(self) -> "Client":
264
+ return self
265
+
266
+ def __exit__(self, *_: Any) -> None:
267
+ self.close()
268
+
269
+ def close(self) -> None:
270
+ """Release the underlying HTTP connections."""
271
+ self._transport.close()
272
+
273
+ def __repr__(self) -> str:
274
+ return (
275
+ f"Client(base_url={self._config.base_url!r}, "
276
+ f"session={self._session!r})"
277
+ )