pipecatcloud 0.2.1__tar.gz → 0.2.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.
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/CHANGELOG.md +38 -2
- {pipecatcloud-0.2.1/src/pipecatcloud.egg-info → pipecatcloud-0.2.2}/PKG-INFO +5 -5
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/pyproject.toml +5 -5
- pipecatcloud-0.2.2/pytest.ini +14 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/agent.py +27 -6
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/agent.py +15 -2
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2/src/pipecatcloud.egg-info}/PKG-INFO +5 -5
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/SOURCES.txt +4 -1
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/requires.txt +4 -4
- pipecatcloud-0.2.2/tests/__init__.py +1 -0
- pipecatcloud-0.2.2/tests/test_agent_sessions.py +70 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/.github/workflows/publish-pypi.yml +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/.github/workflows/publish-test.yml +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/.github/workflows/python-publish.yml +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/.gitignore +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/LICENSE +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/README.md +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/dev-requirements.txt +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/pipecat-cloud.png +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/setup.cfg +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/__init__.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/__main__.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/__version__.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/__init__.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/async_utils.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/auth_utils.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/console_utils.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/deploy_utils.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/local_runner.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/api.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/__init__.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/api.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/__init__.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/auth.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/deploy.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/init.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/organizations.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/run.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/secrets.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/config.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/entry_point.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/config.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/exception.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/py.typed +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud/session.py +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
- {pipecatcloud-0.2.1 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/top_level.txt +0 -0
|
@@ -5,10 +5,46 @@ All notable changes to **Pipecat Cloud** will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [0.2.2] - 2025-08-18
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added `RunnerArguments` as a fallback type in the event that the Pipecat
|
|
13
|
+
development runner is not imported.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Updated the `typer` dependency to support a range of versions in order to
|
|
18
|
+
resolve conflicts with other packages. The new range supported is:
|
|
19
|
+
`"typer>=0.15.3,<0.17.0"`.
|
|
20
|
+
|
|
21
|
+
- Relaxed the package requirements for `python-dotenv` and `uvicorn` to make it
|
|
22
|
+
easier to work with Pipecat Cloud. The new supported versions are:
|
|
23
|
+
|
|
24
|
+
- `"python-dotenv>=1.0.1,<2.0.0"`
|
|
25
|
+
- `"uvicorn>=0.32.0,<1.0.0"`
|
|
26
|
+
|
|
27
|
+
- Updated all types to inherit from `RunnerArguments` to align the types with
|
|
28
|
+
the Pipecat development runner types. This adds types:
|
|
29
|
+
|
|
30
|
+
- `handle_sigint`
|
|
31
|
+
- `handle_sigterm`
|
|
32
|
+
- `pipeline_idle_timeout_secs`
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Fixed `ZeroDivisionError` in `agent sessions` command when calculating
|
|
37
|
+
metrics for agents with zero sessions.
|
|
38
|
+
|
|
39
|
+
- Fixed `UnboundLocalError` in `agent sessions` command where
|
|
40
|
+
`metric_renderables` was referenced before assignment due to earlier logic
|
|
41
|
+
failures.
|
|
42
|
+
|
|
43
|
+
- `agent sessions` command previously threw `AttributeError` when no agent name
|
|
44
|
+
was provided via command line or `pcc-deploy.toml`, it now exits gracefully
|
|
45
|
+
with a clear error message.
|
|
10
46
|
|
|
11
|
-
##
|
|
47
|
+
## [0.2.1] - 2025-08-02
|
|
12
48
|
|
|
13
49
|
### Added
|
|
14
50
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pipecatcloud
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Cloud hosting for Pipecat AI applications
|
|
5
5
|
License: BSD 2-Clause License
|
|
6
6
|
Project-URL: Website, https://docs.pipecat.daily.co/
|
|
@@ -11,14 +11,14 @@ License-File: LICENSE
|
|
|
11
11
|
Requires-Dist: aiohttp<4.0.0,>=3.11.12
|
|
12
12
|
Requires-Dist: fastapi<0.117.0,>=0.115.6
|
|
13
13
|
Requires-Dist: loguru~=0.7.3
|
|
14
|
-
Requires-Dist: python-dotenv
|
|
15
|
-
Requires-Dist: uvicorn
|
|
16
|
-
Requires-Dist: typer
|
|
14
|
+
Requires-Dist: python-dotenv<2.0.0,>=1.0.1
|
|
15
|
+
Requires-Dist: uvicorn<1.0.0,>=0.32.0
|
|
16
|
+
Requires-Dist: typer<0.17.0,>=0.15.3
|
|
17
17
|
Requires-Dist: synchronicity~=0.7.6
|
|
18
18
|
Requires-Dist: toml~=0.10.2
|
|
19
19
|
Requires-Dist: questionary~=2.1.0
|
|
20
20
|
Provides-Extra: pipecat
|
|
21
|
-
Requires-Dist: pipecat-ai>=0.0.
|
|
21
|
+
Requires-Dist: pipecat-ai>=0.0.79; extra == "pipecat"
|
|
22
22
|
Dynamic: license-file
|
|
23
23
|
|
|
24
24
|
<h1><div align="center">
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pipecatcloud"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
requires-python = ">=3.10"
|
|
9
9
|
description = "Cloud hosting for Pipecat AI applications"
|
|
10
10
|
license = { text = "BSD 2-Clause License" }
|
|
@@ -14,16 +14,16 @@ dependencies = [
|
|
|
14
14
|
"aiohttp>=3.11.12,<4.0.0",
|
|
15
15
|
"fastapi>=0.115.6,<0.117.0",
|
|
16
16
|
"loguru~=0.7.3",
|
|
17
|
-
"python-dotenv
|
|
18
|
-
"uvicorn
|
|
19
|
-
"typer
|
|
17
|
+
"python-dotenv>=1.0.1,<2.0.0",
|
|
18
|
+
"uvicorn>=0.32.0,<1.0.0",
|
|
19
|
+
"typer>=0.15.3,<0.17.0",
|
|
20
20
|
"synchronicity~=0.7.6",
|
|
21
21
|
"toml~=0.10.2",
|
|
22
22
|
"questionary~=2.1.0"
|
|
23
23
|
]
|
|
24
24
|
|
|
25
25
|
[project.optional-dependencies]
|
|
26
|
-
pipecat = ["pipecat-ai>=0.0.
|
|
26
|
+
pipecat = ["pipecat-ai>=0.0.79"]
|
|
27
27
|
|
|
28
28
|
[project.scripts]
|
|
29
29
|
pcc = "pipecatcloud.__main__:main"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[tool:pytest]
|
|
2
|
+
# Basic pytest configuration
|
|
3
|
+
|
|
4
|
+
testpaths = tests
|
|
5
|
+
python_files = test_*.py
|
|
6
|
+
# Modern import mode for better import control with src/ layout
|
|
7
|
+
addopts = --import-mode=importlib
|
|
8
|
+
|
|
9
|
+
# Async support for CLI command tests
|
|
10
|
+
asyncio_mode = auto
|
|
11
|
+
|
|
12
|
+
# Markers actually used in tests
|
|
13
|
+
markers =
|
|
14
|
+
asyncio: mark test as async test
|
|
@@ -14,6 +14,7 @@ from fastapi import WebSocket
|
|
|
14
14
|
try:
|
|
15
15
|
from pipecat.runner.types import (
|
|
16
16
|
DailyRunnerArguments,
|
|
17
|
+
RunnerArguments,
|
|
17
18
|
WebSocketRunnerArguments,
|
|
18
19
|
)
|
|
19
20
|
|
|
@@ -23,7 +24,25 @@ except ImportError:
|
|
|
23
24
|
|
|
24
25
|
# Fallback definitions
|
|
25
26
|
@dataclass
|
|
26
|
-
class
|
|
27
|
+
class RunnerArguments:
|
|
28
|
+
"""Base class for runner session arguments.
|
|
29
|
+
|
|
30
|
+
.. deprecated:: 0.2.2
|
|
31
|
+
Install pipecatcloud[pipecat] for better compatibility. This class
|
|
32
|
+
will be removed in a future release.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
handle_sigint: bool
|
|
36
|
+
handle_sigterm: bool
|
|
37
|
+
pipeline_idle_timeout_secs: int
|
|
38
|
+
|
|
39
|
+
def __post_init__(self):
|
|
40
|
+
self.handle_sigint = False
|
|
41
|
+
self.handle_sigterm = False
|
|
42
|
+
self.pipeline_idle_timeout_secs = 300
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class DailyRunnerArguments(RunnerArguments):
|
|
27
46
|
"""Fallback Daily runner arguments when pipecat-ai not available.
|
|
28
47
|
|
|
29
48
|
.. deprecated:: 0.2.1
|
|
@@ -35,7 +54,7 @@ except ImportError:
|
|
|
35
54
|
body: Any
|
|
36
55
|
|
|
37
56
|
@dataclass
|
|
38
|
-
class WebSocketRunnerArguments:
|
|
57
|
+
class WebSocketRunnerArguments(RunnerArguments):
|
|
39
58
|
"""Fallback WebSocket runner arguments when pipecat-ai not available.
|
|
40
59
|
|
|
41
60
|
.. deprecated:: 0.2.1
|
|
@@ -72,13 +91,13 @@ class SessionArguments:
|
|
|
72
91
|
|
|
73
92
|
|
|
74
93
|
@dataclass
|
|
75
|
-
class PipecatSessionArguments(SessionArguments):
|
|
94
|
+
class PipecatSessionArguments(RunnerArguments, SessionArguments):
|
|
76
95
|
"""Standard Pipecat Cloud agent session arguments.
|
|
77
96
|
|
|
78
|
-
|
|
97
|
+
Inherits from RunnerArguments for compatibility with pipecat-ai runner.
|
|
98
|
+
When pipecat-ai is not installed, uses a fallback implementation (deprecated).
|
|
79
99
|
|
|
80
|
-
|
|
81
|
-
body (Any): The body of the request.
|
|
100
|
+
For best compatibility, install: pip install pipecatcloud[pipecat]
|
|
82
101
|
"""
|
|
83
102
|
|
|
84
103
|
body: Any
|
|
@@ -95,6 +114,7 @@ class DailySessionArguments(DailyRunnerArguments, SessionArguments):
|
|
|
95
114
|
"""
|
|
96
115
|
|
|
97
116
|
def __post_init__(self):
|
|
117
|
+
DailyRunnerArguments.__post_init__(self)
|
|
98
118
|
_warn_standalone_usage()
|
|
99
119
|
|
|
100
120
|
|
|
@@ -109,4 +129,5 @@ class WebSocketSessionArguments(WebSocketRunnerArguments, SessionArguments):
|
|
|
109
129
|
"""
|
|
110
130
|
|
|
111
131
|
def __post_init__(self):
|
|
132
|
+
WebSocketRunnerArguments.__post_init__(self)
|
|
112
133
|
_warn_standalone_usage()
|
|
@@ -220,7 +220,14 @@ async def sessions(
|
|
|
220
220
|
),
|
|
221
221
|
):
|
|
222
222
|
org = organization or config.get("org")
|
|
223
|
-
|
|
223
|
+
|
|
224
|
+
# Get agent name from argument or deploy config
|
|
225
|
+
if not agent_name:
|
|
226
|
+
if deploy_config and deploy_config.agent_name:
|
|
227
|
+
agent_name = deploy_config.agent_name
|
|
228
|
+
else:
|
|
229
|
+
console.error("No target agent name provided")
|
|
230
|
+
return typer.Exit(1)
|
|
224
231
|
|
|
225
232
|
with Live(
|
|
226
233
|
console.status(f"[dim]Looking up agent with name '{agent_name}'[/dim]", spinner="dots")
|
|
@@ -257,9 +264,10 @@ async def sessions(
|
|
|
257
264
|
bot_start_metrics = calculate_percentiles(bot_start_times)
|
|
258
265
|
duration_metrics = calculate_percentiles(durations)
|
|
259
266
|
cold_starts_count = sum(1 for s in sessions_list if s.get("coldStart") is True)
|
|
260
|
-
|
|
267
|
+
metric_renderables = [] # Initialize to empty list for type consistency
|
|
261
268
|
|
|
262
269
|
if duration_metrics and bot_start_metrics and total_sessions > 0:
|
|
270
|
+
cold_start_percent = cold_starts_count / total_sessions * 100
|
|
263
271
|
metric_renderables = [
|
|
264
272
|
Panel(
|
|
265
273
|
f"[bold]Total Sessions:[/bold]\n{total_sessions}\n ",
|
|
@@ -289,6 +297,11 @@ async def sessions(
|
|
|
289
297
|
table.add_column("Cold Start")
|
|
290
298
|
|
|
291
299
|
for session in data.get("sessions", []):
|
|
300
|
+
# Note: session["sessionId"] is accessed without defensive checks.
|
|
301
|
+
# If the API returns malformed data missing sessionId, the CLI will crash with
|
|
302
|
+
# a KeyError rather than silently skip sessions. This ensures smoke tests and
|
|
303
|
+
# API verification catch breaking changes immediately. We could instead use
|
|
304
|
+
# console.error() and skip the session but its unclear if thats better..
|
|
292
305
|
if session_id and session["sessionId"] != session_id:
|
|
293
306
|
continue
|
|
294
307
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pipecatcloud
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Cloud hosting for Pipecat AI applications
|
|
5
5
|
License: BSD 2-Clause License
|
|
6
6
|
Project-URL: Website, https://docs.pipecat.daily.co/
|
|
@@ -11,14 +11,14 @@ License-File: LICENSE
|
|
|
11
11
|
Requires-Dist: aiohttp<4.0.0,>=3.11.12
|
|
12
12
|
Requires-Dist: fastapi<0.117.0,>=0.115.6
|
|
13
13
|
Requires-Dist: loguru~=0.7.3
|
|
14
|
-
Requires-Dist: python-dotenv
|
|
15
|
-
Requires-Dist: uvicorn
|
|
16
|
-
Requires-Dist: typer
|
|
14
|
+
Requires-Dist: python-dotenv<2.0.0,>=1.0.1
|
|
15
|
+
Requires-Dist: uvicorn<1.0.0,>=0.32.0
|
|
16
|
+
Requires-Dist: typer<0.17.0,>=0.15.3
|
|
17
17
|
Requires-Dist: synchronicity~=0.7.6
|
|
18
18
|
Requires-Dist: toml~=0.10.2
|
|
19
19
|
Requires-Dist: questionary~=2.1.0
|
|
20
20
|
Provides-Extra: pipecat
|
|
21
|
-
Requires-Dist: pipecat-ai>=0.0.
|
|
21
|
+
Requires-Dist: pipecat-ai>=0.0.79; extra == "pipecat"
|
|
22
22
|
Dynamic: license-file
|
|
23
23
|
|
|
24
24
|
<h1><div align="center">
|
|
@@ -5,6 +5,7 @@ README.md
|
|
|
5
5
|
dev-requirements.txt
|
|
6
6
|
pipecat-cloud.png
|
|
7
7
|
pyproject.toml
|
|
8
|
+
pytest.ini
|
|
8
9
|
.github/workflows/publish-pypi.yml
|
|
9
10
|
.github/workflows/publish-test.yml
|
|
10
11
|
.github/workflows/python-publish.yml
|
|
@@ -40,4 +41,6 @@ src/pipecatcloud/cli/commands/deploy.py
|
|
|
40
41
|
src/pipecatcloud/cli/commands/init.py
|
|
41
42
|
src/pipecatcloud/cli/commands/organizations.py
|
|
42
43
|
src/pipecatcloud/cli/commands/run.py
|
|
43
|
-
src/pipecatcloud/cli/commands/secrets.py
|
|
44
|
+
src/pipecatcloud/cli/commands/secrets.py
|
|
45
|
+
tests/__init__.py
|
|
46
|
+
tests/test_agent_sessions.py
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
aiohttp<4.0.0,>=3.11.12
|
|
2
2
|
fastapi<0.117.0,>=0.115.6
|
|
3
3
|
loguru~=0.7.3
|
|
4
|
-
python-dotenv
|
|
5
|
-
uvicorn
|
|
6
|
-
typer
|
|
4
|
+
python-dotenv<2.0.0,>=1.0.1
|
|
5
|
+
uvicorn<1.0.0,>=0.32.0
|
|
6
|
+
typer<0.17.0,>=0.15.3
|
|
7
7
|
synchronicity~=0.7.6
|
|
8
8
|
toml~=0.10.2
|
|
9
9
|
questionary~=2.1.0
|
|
10
10
|
|
|
11
11
|
[pipecat]
|
|
12
|
-
pipecat-ai>=0.0.
|
|
12
|
+
pipecat-ai>=0.0.79
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Test package for pipecatcloud
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for the 'pcc agent sessions' command.
|
|
3
|
+
|
|
4
|
+
Tests focus on core behaviors and edge cases, not implementation details.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
from unittest.mock import patch
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
# Import the function under test from local source
|
|
12
|
+
from src.pipecatcloud.cli.commands.agent import sessions
|
|
13
|
+
|
|
14
|
+
# Test constants
|
|
15
|
+
TEST_ORG = "test-org"
|
|
16
|
+
TEST_AGENT = "test-agent"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestAgentSessionsCommand:
|
|
20
|
+
"""Test the 'pcc agent sessions' command behaviors."""
|
|
21
|
+
|
|
22
|
+
@pytest.fixture
|
|
23
|
+
def mock_api(self):
|
|
24
|
+
"""Mock the underlying API agent_sessions method."""
|
|
25
|
+
with patch('src.pipecatcloud.cli.commands.agent.API._agent_sessions') as mock_api:
|
|
26
|
+
yield mock_api
|
|
27
|
+
|
|
28
|
+
def test_handles_zero_sessions_without_crash(self, mock_api):
|
|
29
|
+
"""Agent with zero sessions should not cause ZeroDivisionError."""
|
|
30
|
+
# Arrange: API returns empty sessions list
|
|
31
|
+
empty_sessions_response = {"sessions": []}
|
|
32
|
+
mock_api.return_value = empty_sessions_response
|
|
33
|
+
|
|
34
|
+
# Act & Assert: Should complete without ZeroDivisionError
|
|
35
|
+
sessions(
|
|
36
|
+
deploy_config=None,
|
|
37
|
+
agent_name=TEST_AGENT,
|
|
38
|
+
session_id=None,
|
|
39
|
+
organization=TEST_ORG
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def test_handles_api_error_gracefully(self, mock_api):
|
|
43
|
+
"""API errors should be handled without crashing."""
|
|
44
|
+
# Arrange: _agent_sessions raises exception (API error)
|
|
45
|
+
mock_api.side_effect = Exception("Agent not found")
|
|
46
|
+
|
|
47
|
+
# Act: Call with API error
|
|
48
|
+
result = sessions(
|
|
49
|
+
deploy_config=None,
|
|
50
|
+
agent_name="nonexistent-agent",
|
|
51
|
+
session_id=None,
|
|
52
|
+
organization=TEST_ORG
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Assert: Should return typer.Exit on error
|
|
56
|
+
assert isinstance(result, type(typer.Exit()))
|
|
57
|
+
|
|
58
|
+
def test_handles_missing_agent_name_gracefully(self):
|
|
59
|
+
"""Command should exit gracefully when no agent name is provided."""
|
|
60
|
+
# Act: Call with no agent name from either source
|
|
61
|
+
result = sessions(
|
|
62
|
+
deploy_config=None, # No deploy config
|
|
63
|
+
agent_name=None, # No agent name argument
|
|
64
|
+
session_id=None,
|
|
65
|
+
organization=TEST_ORG
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# Assert: Should return typer.Exit(1) with error message
|
|
69
|
+
assert isinstance(result, type(typer.Exit()))
|
|
70
|
+
assert result.exit_code == 1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|