pipecatcloud 0.2.0__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.
Files changed (51) hide show
  1. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/CHANGELOG.md +63 -1
  2. {pipecatcloud-0.2.0/src/pipecatcloud.egg-info → pipecatcloud-0.2.2}/PKG-INFO +8 -6
  3. pipecatcloud-0.2.2/dev-requirements.txt +8 -0
  4. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/pyproject.toml +9 -6
  5. pipecatcloud-0.2.2/pytest.ini +14 -0
  6. pipecatcloud-0.2.2/src/pipecatcloud/agent.py +133 -0
  7. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/agent.py +15 -2
  8. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/secrets.py +7 -1
  9. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2/src/pipecatcloud.egg-info}/PKG-INFO +8 -6
  10. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/SOURCES.txt +4 -1
  11. pipecatcloud-0.2.2/src/pipecatcloud.egg-info/requires.txt +12 -0
  12. pipecatcloud-0.2.2/tests/__init__.py +1 -0
  13. pipecatcloud-0.2.2/tests/test_agent_sessions.py +70 -0
  14. pipecatcloud-0.2.0/dev-requirements.txt +0 -8
  15. pipecatcloud-0.2.0/src/pipecatcloud/agent.py +0 -52
  16. pipecatcloud-0.2.0/src/pipecatcloud.egg-info/requires.txt +0 -9
  17. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/.github/workflows/publish-pypi.yml +0 -0
  18. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/.github/workflows/publish-test.yml +0 -0
  19. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/.github/workflows/python-publish.yml +0 -0
  20. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/.gitignore +0 -0
  21. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/LICENSE +0 -0
  22. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/README.md +0 -0
  23. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/pipecat-cloud.png +0 -0
  24. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/setup.cfg +0 -0
  25. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/__init__.py +0 -0
  26. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/__main__.py +0 -0
  27. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/__version__.py +0 -0
  28. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/__init__.py +0 -0
  29. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/async_utils.py +0 -0
  30. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/auth_utils.py +0 -0
  31. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/console_utils.py +0 -0
  32. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/deploy_utils.py +0 -0
  33. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/_utils/local_runner.py +0 -0
  34. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/api.py +0 -0
  35. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/__init__.py +0 -0
  36. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/api.py +0 -0
  37. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/__init__.py +0 -0
  38. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/auth.py +0 -0
  39. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/deploy.py +0 -0
  40. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/init.py +0 -0
  41. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/organizations.py +0 -0
  42. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/commands/run.py +0 -0
  43. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/config.py +0 -0
  44. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/cli/entry_point.py +0 -0
  45. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/config.py +0 -0
  46. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/exception.py +0 -0
  47. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/py.typed +0 -0
  48. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud/session.py +0 -0
  49. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
  50. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
  51. {pipecatcloud-0.2.0 → pipecatcloud-0.2.2}/src/pipecatcloud.egg-info/top_level.txt +0 -0
@@ -5,7 +5,69 @@ 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
- ## [Unreleased]
8
+ ## [0.2.2] - 2025-08-18
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.
46
+
47
+ ## [0.2.1] - 2025-08-02
48
+
49
+ ### Added
50
+
51
+ - Added a `pipecatcloud[pipecat]` extra for installing `pipecat-ai` dependency.
52
+
53
+ ### Changed
54
+
55
+ - Session argument types now inherit from pipecat-ai runner types when available.
56
+ `DailySessionArguments` and `WebSocketSessionArguments` now inherit from
57
+ `pipecat.runner.types` when `pipecat-ai>=0.0.77` is installed to provide
58
+ compatibility with the pipecat-ai development runner.
59
+
60
+ - Add clarifying information to the `pcc secrets image-pull-secret` setup.
61
+
62
+ - Modified the `aiohttp` minimum version to `3.11.12` and expanded `fastapi` to
63
+ `>=0.115.6,<0.117.0` in order to align with `pipecat-ai`.
64
+
65
+ ### Deprecated
66
+
67
+ - When `pipecat-ai` is not installed, session arguments fall back to standalone
68
+ implementations. This fallback behavior is deprecated and will be removed in
69
+ a future version. Install with `pip install pipecatcloud[pipecat]` for the
70
+ preferred implementation.
9
71
 
10
72
  ## [0.2.0] - 2025-07-09
11
73
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pipecatcloud
3
- Version: 0.2.0
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/
@@ -8,15 +8,17 @@ Keywords: pipecat,pipecat-ai,voice,ai,llm
8
8
  Requires-Python: >=3.10
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
- Requires-Dist: aiohttp<4.0.0,~=3.11.13
12
- Requires-Dist: fastapi~=0.115.6
11
+ Requires-Dist: aiohttp<4.0.0,>=3.11.12
12
+ Requires-Dist: fastapi<0.117.0,>=0.115.6
13
13
  Requires-Dist: loguru~=0.7.3
14
- Requires-Dist: python-dotenv~=1.0.1
15
- Requires-Dist: uvicorn~=0.32.0
16
- Requires-Dist: typer~=0.15.3
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
+ Provides-Extra: pipecat
21
+ Requires-Dist: pipecat-ai>=0.0.79; extra == "pipecat"
20
22
  Dynamic: license-file
21
23
 
22
24
  <h1><div align="center">
@@ -0,0 +1,8 @@
1
+ build~=1.2.2
2
+ grpcio-tools~=1.67.1
3
+ pip-tools~=7.4.1
4
+ pyright~=1.1.402
5
+ pytest~=8.4.1
6
+ ruff~=0.12.1
7
+ setuptools~=78.1.1
8
+ setuptools_scm~=8.3.1
@@ -4,24 +4,27 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pipecatcloud"
7
- version = "0.2.0"
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" }
11
11
  readme = "README.md"
12
12
  keywords = ["pipecat", "pipecat-ai", "voice", "ai", "llm"]
13
13
  dependencies = [
14
- "aiohttp~=3.11.13,<4.0.0",
15
- "fastapi~=0.115.6",
14
+ "aiohttp>=3.11.12,<4.0.0",
15
+ "fastapi>=0.115.6,<0.117.0",
16
16
  "loguru~=0.7.3",
17
- "python-dotenv~=1.0.1",
18
- "uvicorn~=0.32.0",
19
- "typer~=0.15.3",
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
+ [project.optional-dependencies]
26
+ pipecat = ["pipecat-ai>=0.0.79"]
27
+
25
28
  [project.scripts]
26
29
  pcc = "pipecatcloud.__main__:main"
27
30
  pipecatcloud = "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
@@ -0,0 +1,133 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
7
+ import warnings
8
+ from dataclasses import dataclass
9
+ from typing import Any, Optional
10
+
11
+ from fastapi import WebSocket
12
+
13
+ # Try to import new types from pipecat-ai
14
+ try:
15
+ from pipecat.runner.types import (
16
+ DailyRunnerArguments,
17
+ RunnerArguments,
18
+ WebSocketRunnerArguments,
19
+ )
20
+
21
+ _PIPECAT_RUNNER_TYPES_AVAILABLE = True
22
+ except ImportError:
23
+ _PIPECAT_RUNNER_TYPES_AVAILABLE = False
24
+
25
+ # Fallback definitions
26
+ @dataclass
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):
46
+ """Fallback Daily runner arguments when pipecat-ai not available.
47
+
48
+ .. deprecated:: 0.2.1
49
+ Install pipecatcloud[pipecat] for better compatibility.
50
+ """
51
+
52
+ room_url: str
53
+ token: str
54
+ body: Any
55
+
56
+ @dataclass
57
+ class WebSocketRunnerArguments(RunnerArguments):
58
+ """Fallback WebSocket runner arguments when pipecat-ai not available.
59
+
60
+ .. deprecated:: 0.2.1
61
+ Install pipecatcloud[pipecat] for better compatibility.
62
+ """
63
+
64
+ websocket: WebSocket
65
+
66
+
67
+ def _warn_standalone_usage():
68
+ """Warn users about standalone session arguments usage."""
69
+ if not _PIPECAT_RUNNER_TYPES_AVAILABLE:
70
+ warnings.warn(
71
+ "Using standalone pipecatcloud session arguments without pipecat-ai. "
72
+ "For better compatibility, install: pip install pipecatcloud[pipecat]. "
73
+ "Standalone mode will be removed in a future release.",
74
+ DeprecationWarning,
75
+ stacklevel=3,
76
+ )
77
+
78
+
79
+ @dataclass
80
+ class SessionArguments:
81
+ """Base class for common agent session arguments.
82
+
83
+ The arguments are received by the bot() entry point.
84
+
85
+ Parameters:
86
+ session_id (Optional[str]): The unique identifier for the session.
87
+ This is used to track the session across requests.
88
+ """
89
+
90
+ session_id: Optional[str]
91
+
92
+
93
+ @dataclass
94
+ class PipecatSessionArguments(RunnerArguments, SessionArguments):
95
+ """Standard Pipecat Cloud agent session arguments.
96
+
97
+ Inherits from RunnerArguments for compatibility with pipecat-ai runner.
98
+ When pipecat-ai is not installed, uses a fallback implementation (deprecated).
99
+
100
+ For best compatibility, install: pip install pipecatcloud[pipecat]
101
+ """
102
+
103
+ body: Any
104
+
105
+
106
+ @dataclass
107
+ class DailySessionArguments(DailyRunnerArguments, SessionArguments):
108
+ """Daily based agent session arguments.
109
+
110
+ Inherits from DailyRunnerArguments for compatibility with pipecat-ai runner.
111
+ When pipecat-ai is not installed, uses a fallback implementation (deprecated).
112
+
113
+ For best compatibility, install: pip install pipecatcloud[pipecat]
114
+ """
115
+
116
+ def __post_init__(self):
117
+ DailyRunnerArguments.__post_init__(self)
118
+ _warn_standalone_usage()
119
+
120
+
121
+ @dataclass
122
+ class WebSocketSessionArguments(WebSocketRunnerArguments, SessionArguments):
123
+ """WebSocket based agent session arguments.
124
+
125
+ Inherits from WebSocketRunnerArguments for compatibility with pipecat-ai runner.
126
+ When pipecat-ai is not installed, uses a fallback implementation (deprecated).
127
+
128
+ For best compatibility, install: pip install pipecatcloud[pipecat]
129
+ """
130
+
131
+ def __post_init__(self):
132
+ WebSocketRunnerArguments.__post_init__(self)
133
+ _warn_standalone_usage()
@@ -220,7 +220,14 @@ async def sessions(
220
220
  ),
221
221
  ):
222
222
  org = organization or config.get("org")
223
- agent_name = agent_name or deploy_config.agent_name
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
- cold_start_percent = cold_starts_count / total_sessions * 100
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
 
@@ -471,8 +471,14 @@ async def image_pull_secret(
471
471
  return typer.Exit(1)
472
472
 
473
473
  if not credentials:
474
+ console.print(
475
+ "[cyan]For more information about image pull secrets, see: "
476
+ "https://docs.pipecat.daily.co/agents/secrets#image-pull-secrets[/cyan]\n"
477
+ )
474
478
  username = await questionary.text(f"Username for image repository '{host}'").ask_async()
475
- password = await questionary.password(f"Password for image repository '{host}'").ask_async()
479
+ password = await questionary.password(
480
+ f"Access token for image repository '{host}'"
481
+ ).ask_async()
476
482
  if not username or not password:
477
483
  console.print("[bold red]Image pull secret creation cancelled[/bold red]")
478
484
  return typer.Exit(1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pipecatcloud
3
- Version: 0.2.0
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/
@@ -8,15 +8,17 @@ Keywords: pipecat,pipecat-ai,voice,ai,llm
8
8
  Requires-Python: >=3.10
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
- Requires-Dist: aiohttp<4.0.0,~=3.11.13
12
- Requires-Dist: fastapi~=0.115.6
11
+ Requires-Dist: aiohttp<4.0.0,>=3.11.12
12
+ Requires-Dist: fastapi<0.117.0,>=0.115.6
13
13
  Requires-Dist: loguru~=0.7.3
14
- Requires-Dist: python-dotenv~=1.0.1
15
- Requires-Dist: uvicorn~=0.32.0
16
- Requires-Dist: typer~=0.15.3
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
+ Provides-Extra: pipecat
21
+ Requires-Dist: pipecat-ai>=0.0.79; extra == "pipecat"
20
22
  Dynamic: license-file
21
23
 
22
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
@@ -0,0 +1,12 @@
1
+ aiohttp<4.0.0,>=3.11.12
2
+ fastapi<0.117.0,>=0.115.6
3
+ loguru~=0.7.3
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
+ synchronicity~=0.7.6
8
+ toml~=0.10.2
9
+ questionary~=2.1.0
10
+
11
+ [pipecat]
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
@@ -1,8 +0,0 @@
1
- build~=1.2.1
2
- grpcio-tools~=1.62.2
3
- pip-tools~=7.4.1
4
- pyright~=1.1.376
5
- pytest~=8.3.2
6
- ruff~=0.6.7
7
- setuptools~=72.2.0
8
- setuptools_scm~=8.1.0
@@ -1,52 +0,0 @@
1
- #
2
- # Copyright (c) 2025, Daily
3
- #
4
- # SPDX-License-Identifier: BSD 2-Clause License
5
- #
6
-
7
- from dataclasses import dataclass
8
- from typing import Any, Optional
9
-
10
- from fastapi import WebSocket
11
-
12
-
13
- @dataclass
14
- class SessionArguments:
15
- """Base class for common agent session arguments. The arguments are received
16
- by the bot() entry point.
17
-
18
- """
19
-
20
- session_id: Optional[str]
21
-
22
-
23
- @dataclass
24
- class PipecatSessionArguments(SessionArguments):
25
- """Standard Pipecat Cloud agent session arguments. The arguments are
26
- received by the bot() entry point.
27
-
28
- """
29
-
30
- body: Any
31
-
32
-
33
- @dataclass
34
- class DailySessionArguments(SessionArguments):
35
- """Daily based agent session arguments. The arguments are received by the
36
- bot() entry point.
37
-
38
- """
39
-
40
- room_url: str
41
- token: str
42
- body: Any
43
-
44
-
45
- @dataclass
46
- class WebSocketSessionArguments(SessionArguments):
47
- """Websocket based agent session arguments. The arguments are received by
48
- the bot() entry point.
49
-
50
- """
51
-
52
- websocket: WebSocket
@@ -1,9 +0,0 @@
1
- aiohttp<4.0.0,~=3.11.13
2
- fastapi~=0.115.6
3
- loguru~=0.7.3
4
- python-dotenv~=1.0.1
5
- uvicorn~=0.32.0
6
- typer~=0.15.3
7
- synchronicity~=0.7.6
8
- toml~=0.10.2
9
- questionary~=2.1.0
File without changes
File without changes
File without changes
File without changes