dailybot-cli 3.5.0__tar.gz → 3.5.2__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 (50) hide show
  1. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/PKG-INFO +1 -1
  2. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/api_client.py +82 -38
  3. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli.egg-info/PKG-INFO +1 -1
  4. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/pyproject.toml +1 -1
  5. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/LICENSE +0 -0
  6. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/README.md +0 -0
  7. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/__init__.py +0 -0
  8. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/__init__.py +0 -0
  9. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/agent.py +0 -0
  10. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/ask.py +0 -0
  11. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/auth.py +0 -0
  12. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/authoring_helpers.py +0 -0
  13. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/channels.py +0 -0
  14. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/chat.py +0 -0
  15. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/checkin.py +0 -0
  16. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/config.py +0 -0
  17. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/conversation.py +0 -0
  18. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/form.py +0 -0
  19. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/hook.py +0 -0
  20. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/identity.py +0 -0
  21. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/interactive.py +0 -0
  22. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/interactive_chat.py +0 -0
  23. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/kudos.py +0 -0
  24. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/public_api_helpers.py +0 -0
  25. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/query_options.py +0 -0
  26. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/status.py +0 -0
  27. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/team.py +0 -0
  28. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/uninstall.py +0 -0
  29. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/update.py +0 -0
  30. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/upgrade.py +0 -0
  31. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/user.py +0 -0
  32. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/user_scoped_actions.py +0 -0
  33. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/version.py +0 -0
  34. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/commands/workflow.py +0 -0
  35. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/config.py +0 -0
  36. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/display.py +0 -0
  37. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/install_method.py +0 -0
  38. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/ledger.py +0 -0
  39. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/main.py +0 -0
  40. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/tui/__init__.py +0 -0
  41. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/tui/app.py +0 -0
  42. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/tui/commands.py +0 -0
  43. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/tui/conversation.py +0 -0
  44. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli/tui/intents.py +0 -0
  45. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli.egg-info/SOURCES.txt +0 -0
  46. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli.egg-info/dependency_links.txt +0 -0
  47. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli.egg-info/entry_points.txt +0 -0
  48. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli.egg-info/requires.txt +0 -0
  49. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/dailybot_cli.egg-info/top_level.txt +0 -0
  50. {dailybot_cli-3.5.0 → dailybot_cli-3.5.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dailybot-cli
3
- Version: 3.5.0
3
+ Version: 3.5.2
4
4
  Summary: Dailybot CLI - The command-line bridge between humans and agents. Progress reports, observability, and workflow automation for modern teams across Slack, Google Chat, Discord, MS Teams, and more.
5
5
  Author-email: Dailybot <support@dailybot.com>
6
6
  License: MIT
@@ -156,21 +156,77 @@ class DailyBotClient:
156
156
  return headers
157
157
 
158
158
  def _agent_headers(self) -> dict[str, str]:
159
- """Build headers for agent authentication (API key preferred, then Bearer)."""
159
+ """Build headers for agent authentication.
160
+
161
+ Uses the same priority as ``_headers()`` — Bearer first, API key
162
+ second — so that all endpoints behave consistently. The server
163
+ accepts both on every ``/v1/agent*`` endpoint.
164
+ """
160
165
  headers: dict[str, str] = {
161
166
  "Content-Type": "application/json",
162
167
  "Accept": "application/json",
163
168
  }
164
- if self.api_key:
165
- headers["X-API-KEY"] = self.api_key
166
- self._agent_auth_mode = "api_key"
167
- elif self.token:
169
+ if self.token:
168
170
  headers["Authorization"] = f"Bearer {self.token}"
169
171
  self._agent_auth_mode = "bearer"
172
+ elif self.api_key:
173
+ headers["X-API-KEY"] = self.api_key
174
+ self._agent_auth_mode = "api_key"
170
175
  else:
171
176
  self._agent_auth_mode = None
172
177
  return headers
173
178
 
179
+ def _alt_auth_headers(self) -> dict[str, str] | None:
180
+ """Build headers using the alternative credential for a 401 retry.
181
+
182
+ If the primary was Bearer, tries API key; if the primary was API key,
183
+ tries Bearer. Returns ``None`` when no alternative is available.
184
+ """
185
+ headers: dict[str, str] = {
186
+ "Content-Type": "application/json",
187
+ "Accept": "application/json",
188
+ }
189
+ if self._agent_auth_mode == "bearer" and self.api_key:
190
+ headers["X-API-KEY"] = self.api_key
191
+ self._agent_auth_mode = "api_key"
192
+ return headers
193
+ if self._agent_auth_mode == "api_key" and self.token:
194
+ headers["Authorization"] = f"Bearer {self.token}"
195
+ self._agent_auth_mode = "bearer"
196
+ return headers
197
+ return None
198
+
199
+ def _agent_request(
200
+ self,
201
+ method: str,
202
+ url: str,
203
+ *,
204
+ json: dict[str, Any] | None = None,
205
+ params: dict[str, Any] | None = None,
206
+ ) -> httpx.Response:
207
+ """Execute an agent-authenticated request with automatic alt-credential retry.
208
+
209
+ Tries with ``_agent_headers()`` (Bearer preferred, API key fallback).
210
+ If the server returns 401 and an alternative credential is available,
211
+ retries once with it. This covers both directions: expired Bearer
212
+ retried with API key, and stale API key retried with Bearer.
213
+ """
214
+ kwargs: dict[str, Any] = {"headers": self._agent_headers(), "timeout": self.timeout}
215
+ if json is not None:
216
+ kwargs["json"] = json
217
+ if params is not None:
218
+ kwargs["params"] = params
219
+
220
+ response: httpx.Response = httpx.request(method, url, **kwargs)
221
+
222
+ if response.status_code == 401:
223
+ alt: dict[str, str] | None = self._alt_auth_headers()
224
+ if alt is not None:
225
+ kwargs["headers"] = alt
226
+ response = httpx.request(method, url, **kwargs)
227
+
228
+ return response
229
+
174
230
  def _handle_response(self, response: httpx.Response) -> dict[str, Any]:
175
231
  """Parse API response and raise on errors."""
176
232
  if response.status_code >= 400:
@@ -1420,11 +1476,10 @@ class DailyBotClient:
1420
1476
  payload["is_milestone"] = True
1421
1477
  if co_authors:
1422
1478
  payload["co_authors"] = co_authors
1423
- response: httpx.Response = httpx.post(
1479
+ response: httpx.Response = self._agent_request(
1480
+ "POST",
1424
1481
  f"{self.api_url}/v1/agent-reports/",
1425
1482
  json=payload,
1426
- headers=self._agent_headers(),
1427
- timeout=self.timeout,
1428
1483
  )
1429
1484
  return self._handle_response(response)
1430
1485
 
@@ -1441,21 +1496,19 @@ class DailyBotClient:
1441
1496
  }
1442
1497
  if message:
1443
1498
  payload["message"] = message
1444
- response: httpx.Response = httpx.post(
1499
+ response: httpx.Response = self._agent_request(
1500
+ "POST",
1445
1501
  f"{self.api_url}/v1/agent-health/",
1446
1502
  json=payload,
1447
- headers=self._agent_headers(),
1448
- timeout=self.timeout,
1449
1503
  )
1450
1504
  return self._handle_response(response)
1451
1505
 
1452
1506
  def get_agent_health(self, agent_name: str) -> dict[str, Any]:
1453
1507
  """GET /v1/agent-health/?agent_name=..."""
1454
- response: httpx.Response = httpx.get(
1508
+ response: httpx.Response = self._agent_request(
1509
+ "GET",
1455
1510
  f"{self.api_url}/v1/agent-health/",
1456
1511
  params={"agent_name": agent_name},
1457
- headers=self._agent_headers(),
1458
- timeout=self.timeout,
1459
1512
  )
1460
1513
  return self._handle_response(response)
1461
1514
 
@@ -1474,22 +1527,19 @@ class DailyBotClient:
1474
1527
  }
1475
1528
  if webhook_secret:
1476
1529
  payload["webhook_secret"] = webhook_secret
1477
- response: httpx.Response = httpx.post(
1530
+ response: httpx.Response = self._agent_request(
1531
+ "POST",
1478
1532
  f"{self.api_url}/v1/agent-webhook/",
1479
1533
  json=payload,
1480
- headers=self._agent_headers(),
1481
- timeout=self.timeout,
1482
1534
  )
1483
1535
  return self._handle_response(response)
1484
1536
 
1485
1537
  def unregister_agent_webhook(self, agent_name: str) -> dict[str, Any]:
1486
1538
  """DELETE /v1/agent-webhook/"""
1487
- response: httpx.Response = httpx.request(
1539
+ response: httpx.Response = self._agent_request(
1488
1540
  "DELETE",
1489
1541
  f"{self.api_url}/v1/agent-webhook/",
1490
1542
  json={"agent_name": agent_name},
1491
- headers=self._agent_headers(),
1492
- timeout=self.timeout,
1493
1543
  )
1494
1544
  return self._handle_response(response)
1495
1545
 
@@ -1512,11 +1562,10 @@ class DailyBotClient:
1512
1562
  }
1513
1563
  if metadata:
1514
1564
  payload["metadata"] = metadata
1515
- response: httpx.Response = httpx.post(
1565
+ response: httpx.Response = self._agent_request(
1566
+ "POST",
1516
1567
  f"{self.api_url}/v1/agent-email/send/",
1517
1568
  json=payload,
1518
- headers=self._agent_headers(),
1519
- timeout=self.timeout,
1520
1569
  )
1521
1570
  return self._handle_response(response)
1522
1571
 
@@ -1543,11 +1592,10 @@ class DailyBotClient:
1543
1592
  parent and — when ``thread_responses`` was sent — one id per reply, all
1544
1593
  of which can be fed back in a later call to edit the same message.
1545
1594
  """
1546
- response: httpx.Response = httpx.post(
1595
+ response: httpx.Response = self._agent_request(
1596
+ "POST",
1547
1597
  f"{self.api_url}/v1/send-message/",
1548
1598
  json=payload,
1549
- headers=self._agent_headers(),
1550
- timeout=self.timeout,
1551
1599
  )
1552
1600
  return self._handle_response(response)
1553
1601
 
@@ -1563,11 +1611,10 @@ class DailyBotClient:
1563
1611
  the shared agent header logic (``X-API-KEY`` preferred, else the login
1564
1612
  Bearer token). Returns ``{"channel": "<slack-conversation-id>"}``.
1565
1613
  """
1566
- response: httpx.Response = httpx.post(
1614
+ response: httpx.Response = self._agent_request(
1615
+ "POST",
1567
1616
  f"{self.api_url}/v1/open-conversation/",
1568
1617
  json={"users_uuids": users_uuids},
1569
- headers=self._agent_headers(),
1570
- timeout=self.timeout,
1571
1618
  )
1572
1619
  return self._handle_response(response)
1573
1620
 
@@ -1598,11 +1645,10 @@ class DailyBotClient:
1598
1645
  payload["sender_type"] = sender_type
1599
1646
  if sender_name:
1600
1647
  payload["sender_name"] = sender_name
1601
- response: httpx.Response = httpx.post(
1648
+ response: httpx.Response = self._agent_request(
1649
+ "POST",
1602
1650
  f"{self.api_url}/v1/agent-messages/",
1603
1651
  json=payload,
1604
- headers=self._agent_headers(),
1605
- timeout=self.timeout,
1606
1652
  )
1607
1653
  return self._handle_response(response)
1608
1654
 
@@ -1615,11 +1661,10 @@ class DailyBotClient:
1615
1661
  params: dict[str, str] = {"agent_name": agent_name}
1616
1662
  if delivered is not None:
1617
1663
  params["delivered"] = "true" if delivered else "false"
1618
- response: httpx.Response = httpx.get(
1664
+ response: httpx.Response = self._agent_request(
1665
+ "GET",
1619
1666
  f"{self.api_url}/v1/agent-messages/",
1620
1667
  params=params,
1621
- headers=self._agent_headers(),
1622
- timeout=self.timeout,
1623
1668
  )
1624
1669
  if response.status_code >= 400:
1625
1670
  self._handle_response(response)
@@ -1635,11 +1680,10 @@ class DailyBotClient:
1635
1680
  message_ids: list[str],
1636
1681
  ) -> dict[str, Any]:
1637
1682
  """PATCH /v1/agent-messages/read/"""
1638
- response: httpx.Response = httpx.patch(
1683
+ response: httpx.Response = self._agent_request(
1684
+ "PATCH",
1639
1685
  f"{self.api_url}/v1/agent-messages/read/",
1640
1686
  json={"message_ids": message_ids},
1641
- headers=self._agent_headers(),
1642
- timeout=self.timeout,
1643
1687
  )
1644
1688
  return self._handle_response(response)
1645
1689
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dailybot-cli
3
- Version: 3.5.0
3
+ Version: 3.5.2
4
4
  Summary: Dailybot CLI - The command-line bridge between humans and agents. Progress reports, observability, and workflow automation for modern teams across Slack, Google Chat, Discord, MS Teams, and more.
5
5
  Author-email: Dailybot <support@dailybot.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dailybot-cli"
7
- version = "3.5.0"
7
+ version = "3.5.2"
8
8
  description = "Dailybot CLI - The command-line bridge between humans and agents. Progress reports, observability, and workflow automation for modern teams across Slack, Google Chat, Discord, MS Teams, and more."
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
File without changes
File without changes
File without changes