shiftaiagenticinfra-sdk-python 0.0.6__tar.gz → 0.0.8__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.
Files changed (27) hide show
  1. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/PKG-INFO +37 -11
  2. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/README.md +36 -10
  3. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/pyproject.toml +1 -1
  4. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/analytics_api.py +56 -22
  5. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/messages_api.py +21 -0
  6. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/models/__init__.py +36 -7
  7. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftaiagenticinfra_sdk_python.egg-info/PKG-INFO +37 -11
  8. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/tests/test_integration.py +4 -2
  9. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/setup.cfg +0 -0
  10. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/setup.py +0 -0
  11. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/__init__.py +0 -0
  12. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/__init__.py +0 -0
  13. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/agents_api.py +0 -0
  14. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/conversations_api.py +0 -0
  15. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/internal/__init__.py +0 -0
  16. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/internal/trulens_api.py +0 -0
  17. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/platform_api.py +0 -0
  18. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/platform_session_api.py +0 -0
  19. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/api/users_api.py +0 -0
  20. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/client.py +0 -0
  21. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/http/__init__.py +0 -0
  22. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/http/exceptions.py +0 -0
  23. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftai/http/http_client.py +0 -0
  24. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftaiagenticinfra_sdk_python.egg-info/SOURCES.txt +0 -0
  25. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftaiagenticinfra_sdk_python.egg-info/dependency_links.txt +0 -0
  26. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftaiagenticinfra_sdk_python.egg-info/requires.txt +0 -0
  27. {shiftaiagenticinfra_sdk_python-0.0.6 → shiftaiagenticinfra_sdk_python-0.0.8}/shiftaiagenticinfra_sdk_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shiftaiagenticinfra-sdk-python
3
- Version: 0.0.6
3
+ Version: 0.0.8
4
4
  Summary: Shiftai Agentic Infra Python SDK
5
5
  Author: ShiftAI
6
6
  Author-email: ShiftAI <s.tadakamalla@theshiftai.in>
@@ -46,6 +46,12 @@ This SDK is the official gateway to the Shift AI Agentic Infra services, enablin
46
46
  <a href="https://x.com/shift_ai_first">
47
47
  <img src="https://img.shields.io/badge/X(Twitter)-@shift__ai__first-black?style=for-the-badge&logo=x">
48
48
  </a>
49
+ <a href="https://www.reddit.com/user/TheShiftAI/">
50
+ <img src="https://img.shields.io/badge/Reddit-TheShiftAI-FF4500?style=for-the-badge&logo=reddit">
51
+ </a>
52
+ <a href="https://substack.com/@shiftaifirst">
53
+ <img src="https://img.shields.io/badge/Substack-ShiftAI-orange?style=for-the-badge&logo=substack">
54
+ </a>
49
55
  </p>
50
56
 
51
57
  **ShiftAI** is an AI infrastructure and consulting company focused on building
@@ -63,6 +69,9 @@ AI-driven systems that move beyond experimentation into real-world production.
63
69
  - 🐙 GitHub Organization: https://github.com/shiftaitop
64
70
  - 💼 LinkedIn (Company): https://www.linkedin.com/company/theshiftai-in/
65
71
  - 🐦 Twitter (X): https://x.com/shift_ai_first
72
+ - 🔗 Reddit: https://www.reddit.com/user/TheShiftAI/
73
+ - ✍️ Substack: https://substack.com/@shiftaifirst
74
+
66
75
 
67
76
  ### Founder
68
77
  - **Suresh Gokarakonda**
@@ -302,6 +311,14 @@ Get all messages sent by a specific agent.
302
311
 
303
312
  **Return Type:** `List[PlatformMessage]`
304
313
 
314
+ #### `await messages.delete_message(message_id)`
315
+ delete a message turn (bot message and its paired human message). Idempotent if already deleted.
316
+
317
+ **Parameters:**
318
+ - `message_id` (UUID, required): UUID of the **BOT** message to soft-delete
319
+
320
+ **Return Type:** `Dict[str, Any]` (success: `success`, `message`, `timestamp`; errors: `error`, `message`, `status`, `timestamp`)
321
+
305
322
  ### Users API
306
323
 
307
324
  #### `await users.create(username, email, metadata=None)`
@@ -350,20 +367,29 @@ print(f"Created agent: {agent.name}")
350
367
 
351
368
  ### Analytics API
352
369
 
353
- #### `await analytics.submit_feedback(message_id, like=None, dislike=None, feedback=None, regeneration=None)`
354
- Submit user feedback on a bot message.
370
+ #### `await analytics.submit_feedback(message_id, feedback_title, feedback, liked=None, disliked=None, regeneration=None)`
371
+ Submit user feedback on a BOT message (multiple feedback per message allowed).
355
372
 
356
373
  **Parameters:**
357
- - `message_id` (UUID, **required**): ID of the bot message receiving feedback
358
- - `like` (bool, **optional**): User liked the response (true/false)
359
- - `dislike` (bool, **optional**): User disliked the response (true/false)
360
- - `feedback` (str, **optional**): Text feedback or comments (e.g., "Too verbose", "Perfect answer")
374
+ - `message_id` (UUID, **required**): ID of the BOT message receiving feedback
375
+ - `feedback_title` (str, **required**): Title for the feedback (e.g., "Response Quality Feedback")
376
+ - `feedback` (str, **required**): Feedback content (e.g., "The response was very helpful")
377
+ - `liked` (bool, **optional**): User liked the response (true/false)
378
+ - `disliked` (bool, **optional**): User disliked the response (true/false)
361
379
  - `regeneration` (bool, **optional**): User requested regeneration (true/false)
362
380
 
363
- **Return Type:** `FeedbackSubmissionResponse`
381
+ **Return Type:** `FeedbackSubmissionResponse` (includes `feedbackId`, `submittedAt`)
382
+
383
+ #### `await analytics.get_message_feedback(message_id)`
384
+ Get all feedback submissions for a specific BOT message (most recent first).
385
+
386
+ **Parameters:**
387
+ - `message_id` (UUID, **required**): UUID of the BOT message
388
+
389
+ **Return Type:** `List[FeedbackDTO]`
364
390
 
365
391
  #### `await analytics.get_dashboard()`
366
- Get project dashboard metrics.
392
+ Get project dashboard metrics (includes cache analytics: `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
367
393
 
368
394
  **Return Type:** `DashboardMetricsDTO`
369
395
 
@@ -384,12 +410,12 @@ Get most active users.
384
410
  **Return Type:** `List[TopUserDTO]`
385
411
 
386
412
  #### `await analytics.get_user_analytics()`
387
- Get analytics for all users.
413
+ Get analytics for all users (per-user cache metrics: `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
388
414
 
389
415
  **Return Type:** `List[UserAnalyticsDTO]`
390
416
 
391
417
  #### `await analytics.get_project_data(top_limit=10)`
392
- Get project-level analytics data.
418
+ Get project-level analytics data (includes `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
393
419
 
394
420
  **Parameters:**
395
421
  - `top_limit` (int, **optional**): Limit for top results (default: 10, max: 100)
@@ -17,6 +17,12 @@ This SDK is the official gateway to the Shift AI Agentic Infra services, enablin
17
17
  <a href="https://x.com/shift_ai_first">
18
18
  <img src="https://img.shields.io/badge/X(Twitter)-@shift__ai__first-black?style=for-the-badge&logo=x">
19
19
  </a>
20
+ <a href="https://www.reddit.com/user/TheShiftAI/">
21
+ <img src="https://img.shields.io/badge/Reddit-TheShiftAI-FF4500?style=for-the-badge&logo=reddit">
22
+ </a>
23
+ <a href="https://substack.com/@shiftaifirst">
24
+ <img src="https://img.shields.io/badge/Substack-ShiftAI-orange?style=for-the-badge&logo=substack">
25
+ </a>
20
26
  </p>
21
27
 
22
28
  **ShiftAI** is an AI infrastructure and consulting company focused on building
@@ -34,6 +40,9 @@ AI-driven systems that move beyond experimentation into real-world production.
34
40
  - 🐙 GitHub Organization: https://github.com/shiftaitop
35
41
  - 💼 LinkedIn (Company): https://www.linkedin.com/company/theshiftai-in/
36
42
  - 🐦 Twitter (X): https://x.com/shift_ai_first
43
+ - 🔗 Reddit: https://www.reddit.com/user/TheShiftAI/
44
+ - ✍️ Substack: https://substack.com/@shiftaifirst
45
+
37
46
 
38
47
  ### Founder
39
48
  - **Suresh Gokarakonda**
@@ -273,6 +282,14 @@ Get all messages sent by a specific agent.
273
282
 
274
283
  **Return Type:** `List[PlatformMessage]`
275
284
 
285
+ #### `await messages.delete_message(message_id)`
286
+ delete a message turn (bot message and its paired human message). Idempotent if already deleted.
287
+
288
+ **Parameters:**
289
+ - `message_id` (UUID, required): UUID of the **BOT** message to soft-delete
290
+
291
+ **Return Type:** `Dict[str, Any]` (success: `success`, `message`, `timestamp`; errors: `error`, `message`, `status`, `timestamp`)
292
+
276
293
  ### Users API
277
294
 
278
295
  #### `await users.create(username, email, metadata=None)`
@@ -321,20 +338,29 @@ print(f"Created agent: {agent.name}")
321
338
 
322
339
  ### Analytics API
323
340
 
324
- #### `await analytics.submit_feedback(message_id, like=None, dislike=None, feedback=None, regeneration=None)`
325
- Submit user feedback on a bot message.
341
+ #### `await analytics.submit_feedback(message_id, feedback_title, feedback, liked=None, disliked=None, regeneration=None)`
342
+ Submit user feedback on a BOT message (multiple feedback per message allowed).
326
343
 
327
344
  **Parameters:**
328
- - `message_id` (UUID, **required**): ID of the bot message receiving feedback
329
- - `like` (bool, **optional**): User liked the response (true/false)
330
- - `dislike` (bool, **optional**): User disliked the response (true/false)
331
- - `feedback` (str, **optional**): Text feedback or comments (e.g., "Too verbose", "Perfect answer")
345
+ - `message_id` (UUID, **required**): ID of the BOT message receiving feedback
346
+ - `feedback_title` (str, **required**): Title for the feedback (e.g., "Response Quality Feedback")
347
+ - `feedback` (str, **required**): Feedback content (e.g., "The response was very helpful")
348
+ - `liked` (bool, **optional**): User liked the response (true/false)
349
+ - `disliked` (bool, **optional**): User disliked the response (true/false)
332
350
  - `regeneration` (bool, **optional**): User requested regeneration (true/false)
333
351
 
334
- **Return Type:** `FeedbackSubmissionResponse`
352
+ **Return Type:** `FeedbackSubmissionResponse` (includes `feedbackId`, `submittedAt`)
353
+
354
+ #### `await analytics.get_message_feedback(message_id)`
355
+ Get all feedback submissions for a specific BOT message (most recent first).
356
+
357
+ **Parameters:**
358
+ - `message_id` (UUID, **required**): UUID of the BOT message
359
+
360
+ **Return Type:** `List[FeedbackDTO]`
335
361
 
336
362
  #### `await analytics.get_dashboard()`
337
- Get project dashboard metrics.
363
+ Get project dashboard metrics (includes cache analytics: `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
338
364
 
339
365
  **Return Type:** `DashboardMetricsDTO`
340
366
 
@@ -355,12 +381,12 @@ Get most active users.
355
381
  **Return Type:** `List[TopUserDTO]`
356
382
 
357
383
  #### `await analytics.get_user_analytics()`
358
- Get analytics for all users.
384
+ Get analytics for all users (per-user cache metrics: `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
359
385
 
360
386
  **Return Type:** `List[UserAnalyticsDTO]`
361
387
 
362
388
  #### `await analytics.get_project_data(top_limit=10)`
363
- Get project-level analytics data.
389
+ Get project-level analytics data (includes `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
364
390
 
365
391
  **Parameters:**
366
392
  - `top_limit` (int, **optional**): Limit for top results (default: 10, max: 100)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "shiftaiagenticinfra-sdk-python"
7
- version = "0.0.6"
7
+ version = "0.0.8"
8
8
  description = "Shiftai Agentic Infra Python SDK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -9,6 +9,7 @@ from ..http import HttpClient
9
9
  from ..models import (
10
10
  FeedbackSubmissionRequest,
11
11
  FeedbackSubmissionResponse,
12
+ FeedbackDTO,
12
13
  DashboardMetricsDTO,
13
14
  TopAgentDTO,
14
15
  TopUserDTO,
@@ -26,49 +27,82 @@ class AnalyticsApi:
26
27
  async def submit_feedback(
27
28
  self,
28
29
  message_id: UUID,
29
- like: Optional[bool] = None,
30
- dislike: Optional[bool] = None,
31
- feedback: Optional[str] = None,
30
+ feedback_title: str,
31
+ feedback: str,
32
+ liked: Optional[bool] = None,
33
+ disliked: Optional[bool] = None,
32
34
  regeneration: Optional[bool] = None,
33
35
  ) -> FeedbackSubmissionResponse:
34
36
  """
35
- Submit feedback for a BOT message.
36
-
37
+ Submit feedback for a BOT message (multiple feedback per message allowed).
38
+
37
39
  POST /api/analytics/data
38
-
40
+
39
41
  Args:
40
42
  message_id: The ID of the BOT message that received feedback (required)
41
- like: Like feedback indicator (optional)
42
- dislike: Dislike feedback indicator (optional)
43
- feedback: Optional text feedback or comments (optional)
44
- regeneration: Indicates if user requested to regenerate (optional)
45
-
43
+ feedback_title: Title for the feedback (required)
44
+ feedback: Feedback content (required)
45
+ liked: Like rating (optional)
46
+ disliked: Dislike rating (optional)
47
+ regeneration: User requested regeneration (optional)
48
+
46
49
  Returns:
47
- FeedbackSubmissionResponse
48
-
50
+ FeedbackSubmissionResponse with feedbackId and submittedAt
51
+
49
52
  Raises:
50
- ValueError: If message_id is missing or API key is not configured
53
+ ValueError: If message_id, feedback_title or feedback is missing
51
54
  ApiException: If the API request fails
52
55
  """
53
56
  self._http_client.ensure_authenticated()
54
57
 
55
58
  if message_id is None:
56
59
  raise ValueError("message_id is required")
57
-
60
+ if not feedback_title or not feedback_title.strip():
61
+ raise ValueError("feedback_title is required")
62
+ if not feedback or not feedback.strip():
63
+ raise ValueError("feedback is required")
64
+
58
65
  request = FeedbackSubmissionRequest(
59
66
  messageId=message_id,
60
- like=like,
61
- dislike=dislike,
62
- feedback=feedback,
63
- regeneration=regeneration
67
+ feedbackTitle=feedback_title.strip(),
68
+ feedback=feedback.strip(),
69
+ liked=liked,
70
+ disliked=disliked,
71
+ regeneration=regeneration,
64
72
  )
65
-
73
+
66
74
  return await self._http_client.post(
67
75
  "/api/analytics/data",
68
76
  request,
69
- FeedbackSubmissionResponse
77
+ FeedbackSubmissionResponse,
70
78
  )
71
-
79
+
80
+ async def get_message_feedback(self, message_id: UUID) -> List[FeedbackDTO]:
81
+ """
82
+ Get all feedback submissions for a specific BOT message (most recent first).
83
+
84
+ GET /api/analytics/messages/{messageId}/feedback
85
+
86
+ Args:
87
+ message_id: UUID of the BOT message (required)
88
+
89
+ Returns:
90
+ List of FeedbackDTO, ordered by submittedAt descending
91
+
92
+ Raises:
93
+ ValueError: If message_id is missing
94
+ ApiException: If the API request fails
95
+ """
96
+ self._http_client.ensure_authenticated()
97
+
98
+ if message_id is None:
99
+ raise ValueError("message_id is required")
100
+
101
+ return await self._http_client.get_list(
102
+ f"/api/analytics/messages/{message_id}/feedback",
103
+ FeedbackDTO,
104
+ )
105
+
72
106
  async def get_dashboard(self) -> DashboardMetricsDTO:
73
107
  """
74
108
  Get dashboard metrics.
@@ -11,6 +11,7 @@ from ..models import (
11
11
  PlatformMessageSubmissionResponse,
12
12
  PlatformMessage,
13
13
  AgentData,
14
+ DeleteMessageRequest,
14
15
  )
15
16
 
16
17
 
@@ -291,3 +292,23 @@ class MessagesApi:
291
292
  PlatformMessage
292
293
  )
293
294
 
295
+ async def delete_message(self, message_id: UUID) -> Dict[str, Any]:
296
+ """
297
+ Soft-delete a message turn (bot message and its paired human message).
298
+
299
+ POST /api/platform/messages/delete
300
+
301
+ Idempotent if the message is already deleted. Returns a map with
302
+ success, message, timestamp (or error fields on failure).
303
+
304
+ Args:
305
+ message_id: UUID of the BOT message to soft-delete (required)
306
+
307
+ Returns:
308
+ Dict with success, message, timestamp (or error, message, status, timestamp on error)
309
+ """
310
+ self._http_client.ensure_authenticated()
311
+ if message_id is None:
312
+ raise ValueError("message_id is required")
313
+ request = DeleteMessageRequest(messageId=message_id)
314
+ return await self._http_client.post_map("/api/platform/messages/delete", request)
@@ -152,20 +152,40 @@ class Agent:
152
152
 
153
153
  @dataclass
154
154
  class FeedbackSubmissionRequest:
155
- """Request for submitting feedback."""
156
- messageId: UUID
157
- like: Optional[bool] = None
158
- dislike: Optional[bool] = None
159
- feedback: Optional[str] = None
160
- regeneration: Optional[bool] = None
155
+ """Request for submitting feedback (multiple feedback per BOT message)."""
156
+ messageId: UUID # required - BOT message ID
157
+ feedbackTitle: str # required - Feedback title
158
+ feedback: str # required - Feedback content
159
+ liked: Optional[bool] = None # optional - Like rating (renamed from like)
160
+ disliked: Optional[bool] = None # optional - Dislike rating (renamed from dislike)
161
+ regeneration: Optional[bool] = None # optional - Regeneration request
161
162
 
162
163
 
163
164
  @dataclass
164
165
  class FeedbackSubmissionResponse:
165
166
  """Response from feedback submission."""
166
167
  success: Optional[bool] = None
168
+ feedbackId: Optional[UUID] = None # Feedback entry ID (was botMessageId)
167
169
  message: Optional[str] = None
168
- botMessageId: Optional[UUID] = None
170
+ submittedAt: Optional[str] = None # ISO 8601 datetime string
171
+
172
+
173
+ @dataclass
174
+ class FeedbackDTO:
175
+ """Single feedback entry for a BOT message (GET feedback list)."""
176
+ id: Optional[UUID] = None # Feedback entry ID
177
+ feedbackTitle: Optional[str] = None
178
+ feedback: Optional[str] = None
179
+ liked: Optional[bool] = None
180
+ disliked: Optional[bool] = None
181
+ regeneration: Optional[bool] = None
182
+ submittedAt: Optional[str] = None # ISO 8601 datetime string
183
+
184
+
185
+ @dataclass
186
+ class DeleteMessageRequest:
187
+ """Request for soft-deleting a message turn (bot message and its paired human)."""
188
+ messageId: UUID # required – bot message ID
169
189
 
170
190
 
171
191
  @dataclass(init=False)
@@ -240,6 +260,9 @@ class DashboardMetricsDTO:
240
260
  likes: Optional[int] = None
241
261
  dislikes: Optional[int] = None
242
262
  regenerates: Optional[int] = None
263
+ cacheServed: Optional[int] = None
264
+ estimatedTokensSaved: Optional[int] = None
265
+ estimatedCostSaved: Optional[float] = None
243
266
 
244
267
 
245
268
  @dataclass
@@ -275,6 +298,9 @@ class UserAnalyticsDTO:
275
298
  likes: Optional[int] = None
276
299
  dislikes: Optional[int] = None
277
300
  regenerates: Optional[int] = None
301
+ cacheServed: Optional[int] = None
302
+ estimatedTokensSaved: Optional[int] = None
303
+ estimatedCostSaved: Optional[float] = None
278
304
 
279
305
 
280
306
  @dataclass
@@ -289,6 +315,9 @@ class ProjectAnalyticsResponseDTO:
289
315
  likes: Optional[int] = None
290
316
  dislikes: Optional[int] = None
291
317
  regenerates: Optional[int] = None
318
+ cacheServed: Optional[int] = None
319
+ estimatedTokensSaved: Optional[int] = None
320
+ estimatedCostSaved: Optional[float] = None
292
321
  topUserActivity: Optional[List[Any]] = None
293
322
  topDevicesByUsage: Optional[List[Any]] = None
294
323
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shiftaiagenticinfra-sdk-python
3
- Version: 0.0.6
3
+ Version: 0.0.8
4
4
  Summary: Shiftai Agentic Infra Python SDK
5
5
  Author: ShiftAI
6
6
  Author-email: ShiftAI <s.tadakamalla@theshiftai.in>
@@ -46,6 +46,12 @@ This SDK is the official gateway to the Shift AI Agentic Infra services, enablin
46
46
  <a href="https://x.com/shift_ai_first">
47
47
  <img src="https://img.shields.io/badge/X(Twitter)-@shift__ai__first-black?style=for-the-badge&logo=x">
48
48
  </a>
49
+ <a href="https://www.reddit.com/user/TheShiftAI/">
50
+ <img src="https://img.shields.io/badge/Reddit-TheShiftAI-FF4500?style=for-the-badge&logo=reddit">
51
+ </a>
52
+ <a href="https://substack.com/@shiftaifirst">
53
+ <img src="https://img.shields.io/badge/Substack-ShiftAI-orange?style=for-the-badge&logo=substack">
54
+ </a>
49
55
  </p>
50
56
 
51
57
  **ShiftAI** is an AI infrastructure and consulting company focused on building
@@ -63,6 +69,9 @@ AI-driven systems that move beyond experimentation into real-world production.
63
69
  - 🐙 GitHub Organization: https://github.com/shiftaitop
64
70
  - 💼 LinkedIn (Company): https://www.linkedin.com/company/theshiftai-in/
65
71
  - 🐦 Twitter (X): https://x.com/shift_ai_first
72
+ - 🔗 Reddit: https://www.reddit.com/user/TheShiftAI/
73
+ - ✍️ Substack: https://substack.com/@shiftaifirst
74
+
66
75
 
67
76
  ### Founder
68
77
  - **Suresh Gokarakonda**
@@ -302,6 +311,14 @@ Get all messages sent by a specific agent.
302
311
 
303
312
  **Return Type:** `List[PlatformMessage]`
304
313
 
314
+ #### `await messages.delete_message(message_id)`
315
+ delete a message turn (bot message and its paired human message). Idempotent if already deleted.
316
+
317
+ **Parameters:**
318
+ - `message_id` (UUID, required): UUID of the **BOT** message to soft-delete
319
+
320
+ **Return Type:** `Dict[str, Any]` (success: `success`, `message`, `timestamp`; errors: `error`, `message`, `status`, `timestamp`)
321
+
305
322
  ### Users API
306
323
 
307
324
  #### `await users.create(username, email, metadata=None)`
@@ -350,20 +367,29 @@ print(f"Created agent: {agent.name}")
350
367
 
351
368
  ### Analytics API
352
369
 
353
- #### `await analytics.submit_feedback(message_id, like=None, dislike=None, feedback=None, regeneration=None)`
354
- Submit user feedback on a bot message.
370
+ #### `await analytics.submit_feedback(message_id, feedback_title, feedback, liked=None, disliked=None, regeneration=None)`
371
+ Submit user feedback on a BOT message (multiple feedback per message allowed).
355
372
 
356
373
  **Parameters:**
357
- - `message_id` (UUID, **required**): ID of the bot message receiving feedback
358
- - `like` (bool, **optional**): User liked the response (true/false)
359
- - `dislike` (bool, **optional**): User disliked the response (true/false)
360
- - `feedback` (str, **optional**): Text feedback or comments (e.g., "Too verbose", "Perfect answer")
374
+ - `message_id` (UUID, **required**): ID of the BOT message receiving feedback
375
+ - `feedback_title` (str, **required**): Title for the feedback (e.g., "Response Quality Feedback")
376
+ - `feedback` (str, **required**): Feedback content (e.g., "The response was very helpful")
377
+ - `liked` (bool, **optional**): User liked the response (true/false)
378
+ - `disliked` (bool, **optional**): User disliked the response (true/false)
361
379
  - `regeneration` (bool, **optional**): User requested regeneration (true/false)
362
380
 
363
- **Return Type:** `FeedbackSubmissionResponse`
381
+ **Return Type:** `FeedbackSubmissionResponse` (includes `feedbackId`, `submittedAt`)
382
+
383
+ #### `await analytics.get_message_feedback(message_id)`
384
+ Get all feedback submissions for a specific BOT message (most recent first).
385
+
386
+ **Parameters:**
387
+ - `message_id` (UUID, **required**): UUID of the BOT message
388
+
389
+ **Return Type:** `List[FeedbackDTO]`
364
390
 
365
391
  #### `await analytics.get_dashboard()`
366
- Get project dashboard metrics.
392
+ Get project dashboard metrics (includes cache analytics: `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
367
393
 
368
394
  **Return Type:** `DashboardMetricsDTO`
369
395
 
@@ -384,12 +410,12 @@ Get most active users.
384
410
  **Return Type:** `List[TopUserDTO]`
385
411
 
386
412
  #### `await analytics.get_user_analytics()`
387
- Get analytics for all users.
413
+ Get analytics for all users (per-user cache metrics: `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
388
414
 
389
415
  **Return Type:** `List[UserAnalyticsDTO]`
390
416
 
391
417
  #### `await analytics.get_project_data(top_limit=10)`
392
- Get project-level analytics data.
418
+ Get project-level analytics data (includes `cacheServed`, `estimatedTokensSaved`, `estimatedCostSaved` when available).
393
419
 
394
420
  **Parameters:**
395
421
  - `top_limit` (int, **optional**): Limit for top results (default: 10, max: 100)
@@ -156,12 +156,14 @@ async def test_complete_sdk_flow():
156
156
  print("Step 7: Submitting feedback...")
157
157
  feedback_response = await client.analytics.submit_feedback(
158
158
  message_id=bot_message_id,
159
- like=True,
160
- feedback="Great response, very helpful!"
159
+ feedback_title="Response Quality Feedback",
160
+ feedback="Great response, very helpful!",
161
+ liked=True,
161
162
  )
162
163
 
163
164
  assert feedback_response is not None, "Feedback response should not be null"
164
165
  assert feedback_response.success is True, "Feedback submission should be successful"
166
+ assert feedback_response.feedbackId is not None, "Feedback ID should be returned"
165
167
  print("✓ Feedback submitted\n")
166
168
 
167
169
  # Step 8: Get dashboard metrics