pipecatcloud 0.7.1__tar.gz → 1.0.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.
Files changed (76) hide show
  1. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/.github/workflows/python-compatibility.yml +1 -1
  2. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/.github/workflows/tests.yml +2 -5
  3. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/CHANGELOG.md +92 -0
  4. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/CLAUDE.md +4 -5
  5. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/PKG-INFO +15 -16
  6. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/README.md +14 -15
  7. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/pyproject.toml +10 -5
  8. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/__init__.py +27 -8
  9. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/_utils/console_utils.py +61 -0
  10. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/_utils/deploy_utils.py +18 -26
  11. pipecatcloud-1.0.0/src/pipecatcloud/agent.py +85 -0
  12. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/api.py +34 -1
  13. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/auth.py +6 -17
  14. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/deploy.py +66 -44
  15. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/organizations.py +0 -22
  16. pipecatcloud-1.0.0/src/pipecatcloud/cli/commands/spend_limit.py +260 -0
  17. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/config.py +1 -1
  18. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/entry_point.py +2 -2
  19. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/config.py +1 -0
  20. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud.egg-info/PKG-INFO +15 -16
  21. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud.egg-info/SOURCES.txt +5 -2
  22. pipecatcloud-1.0.0/src/pipecatcloud.egg-info/entry_points.txt +2 -0
  23. pipecatcloud-1.0.0/tests/test_agent_args.py +64 -0
  24. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_agent_sessions.py +2 -2
  25. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_agent_stop.py +2 -2
  26. pipecatcloud-1.0.0/tests/test_deploy_poll.py +43 -0
  27. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_krisp_viva.py +19 -42
  28. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_max_session_duration.py +1 -1
  29. pipecatcloud-1.0.0/tests/test_spend_limit.py +337 -0
  30. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/uv.lock +241 -311
  31. pipecatcloud-0.7.1/src/pipecatcloud/__main__.py +0 -15
  32. pipecatcloud-0.7.1/src/pipecatcloud/agent.py +0 -161
  33. pipecatcloud-0.7.1/src/pipecatcloud.egg-info/entry_points.txt +0 -6
  34. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/.claude/settings.json +0 -0
  35. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/.github/workflows/format.yml +0 -0
  36. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/.github/workflows/publish-pypi.yml +0 -0
  37. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/.github/workflows/publish-test.yml +0 -0
  38. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/.gitignore +0 -0
  39. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/.pre-commit-config.yaml +0 -0
  40. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/LICENSE +0 -0
  41. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/pipecat-cloud.png +0 -0
  42. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/pytest.ini +0 -0
  43. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/scripts/fix-ruff.sh +0 -0
  44. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/setup.cfg +0 -0
  45. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/__version__.py +0 -0
  46. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/_utils/__init__.py +0 -0
  47. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/_utils/async_utils.py +0 -0
  48. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/_utils/auth_utils.py +0 -0
  49. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/_utils/build_utils.py +0 -0
  50. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/_utils/regions.py +0 -0
  51. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/__init__.py +0 -0
  52. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/api.py +0 -0
  53. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/__init__.py +0 -0
  54. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/agent.py +0 -0
  55. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/build.py +0 -0
  56. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/docker.py +0 -0
  57. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/regions.py +0 -0
  58. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/cli/commands/secrets.py +0 -0
  59. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/constants.py +0 -0
  60. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/exception.py +0 -0
  61. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/py.typed +0 -0
  62. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/session.py +0 -0
  63. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud/smallwebrtc/session_manager.py +0 -0
  64. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
  65. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud.egg-info/requires.txt +0 -0
  66. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/src/pipecatcloud.egg-info/top_level.txt +0 -0
  67. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/__init__.py +0 -0
  68. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/conftest.py +0 -0
  69. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_api_client.py +0 -0
  70. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_auth.py +0 -0
  71. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_build_utils.py +0 -0
  72. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_config_file.py +0 -0
  73. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_deployment_status.py +0 -0
  74. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_docker_commands.py +0 -0
  75. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_pat_auth.py +0 -0
  76. {pipecatcloud-0.7.1 → pipecatcloud-1.0.0}/tests/test_regions.py +0 -0
@@ -42,4 +42,4 @@ jobs:
42
42
  - name: Verify CLI loads
43
43
  run: |
44
44
  uv run python --version
45
- uv run pcc --help
45
+ uv run python -c "from pipecatcloud.cli.entry_point import entrypoint_cli_typer"
@@ -33,9 +33,6 @@ jobs:
33
33
  run: |
34
34
  uv sync --group dev
35
35
 
36
- - name: Test Docker commands
36
+ - name: Run tests
37
37
  run: |
38
- uv run pytest tests/test_docker_commands.py -v
39
-
40
- # Note: test_agent_sessions.py is excluded because it requires complex
41
- # API mocking for CI. These tests can be run locally with proper auth.
38
+ uv run pytest -v
@@ -5,6 +5,98 @@ 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
+ ## [1.0.0] - 2026-06-19
9
+
10
+ ### Added
11
+
12
+ - New `pipecat cloud spend-limit` command group for managing the organization-level
13
+ spend cap:
14
+ - `pipecat cloud spend-limit show` prints the current limit, period spend, period
15
+ boundaries, and blocked state. Pass `--json` for machine-readable output.
16
+ - `pipecat cloud spend-limit set <amount>` sets a new limit. The amount is in
17
+ dollars with at most two decimal places (e.g. `50` or `12.34`). The
18
+ command prompts before setting the limit to `$0` or below current
19
+ spend; pass `-y/--yes` to skip the prompt.
20
+ - `pipecat cloud spend-limit clear` removes the limit, with the same confirmation
21
+ behavior.
22
+
23
+ - Any CLI command that surfaces an HTTP 402 `SPEND_LIMIT_REACHED` error now
24
+ renders a wrapped remediation message that explains how to unblock new
25
+ sessions, instead of a generic API error panel.
26
+
27
+ ### Changed
28
+
29
+ - **The agent `*SessionArguments` types are now thin subclasses of pipecat-ai's
30
+ runner argument types** (`SessionArguments`, `PipecatSessionArguments`,
31
+ `DailySessionArguments`, `WebSocketSessionArguments`, `SmallWebRTCSessionArguments`).
32
+ Because each is a subclass of the matching `pipecat.runner.types.*RunnerArguments`,
33
+ it interoperates with pipecat's runner machinery — `create_transport(args)` and
34
+ `isinstance(args, DailyRunnerArguments)` both work — so a bot's `bot()` may type
35
+ the argument as either the `*SessionArguments` type or the underlying
36
+ `*RunnerArguments` type.
37
+
38
+ - **`pipecat-ai` is an optional dependency (`pipecatcloud[pipecat]`).** Only the
39
+ agent session-argument types need it; the SDK (`Session`, the API client) and the
40
+ CLI do not. The types are now lazily imported, so plain `import pipecatcloud`
41
+ works without pipecat-ai installed. *Migration:* if you use the `*SessionArguments`
42
+ types, install `uv add "pipecatcloud[pipecat]"` (or otherwise have pipecat-ai
43
+ in your environment); accessing them without pipecat-ai raises a clear `ImportError`.
44
+ This also removes the old standalone fallback `*RunnerArguments` definitions
45
+ (deprecated since 0.2.1); `pipecatcloud.agent` now imports the real types from
46
+ pipecat-ai.
47
+
48
+ ### Fixed
49
+
50
+ - **`pipecatcloud` now exports `SmallWebRTCSessionArguments`** (the SmallWebRTC agent
51
+ session type), not `SmallWebRTCRunnerArguments`. The `SmallWebRTCSessionArguments`
52
+ dataclass existed but was unreachable from the top-level package, while a pipecat-ai
53
+ runner base type was exported in its place — inconsistent with the other transports'
54
+ `*SessionArguments` exports. `from pipecatcloud import SmallWebRTCRunnerArguments` no
55
+ longer works (import it from `pipecat.runner.types` if you need the base type).
56
+
57
+ ### Removed
58
+
59
+ - **The standalone CLI** (`pcc` / `pipecatcloud` console scripts and `python -m
60
+ pipecatcloud`). Pipecat Cloud is no longer a directly-invocable CLI; its commands are
61
+ exposed through the **Pipecat CLI** as `pipecat cloud ...` (the same commands that have
62
+ been available there for some time). *Migration:* install the Pipecat CLI with
63
+ `uv tool install pipecat-ai-cli` and replace `pcc <command>` with
64
+ `pipecat cloud <command>` (e.g. `pcc auth login` → `pipecat cloud auth login`). The
65
+ Python SDK (`pip install pipecatcloud`) is unchanged.
66
+
67
+ - **Legacy Krisp (the `--enable-krisp` flag and the `enable_krisp` config/API field).**
68
+ The legacy Krisp model is no longer supported anywhere — use **Krisp VIVA**
69
+ (`--krisp-viva-audio-filter`, or the `[krisp_viva]` section in `pcc-deploy.toml`).
70
+ Removed the `--enable-krisp` CLI flag, the `enable_krisp` field on the deploy config,
71
+ its `pcc-deploy.toml` key, and the `enableKrisp` API payload. A `pcc-deploy.toml` that
72
+ still contains `enable_krisp` will now error with a message pointing to `[krisp_viva]` —
73
+ remove it.
74
+
75
+ - **`pipecat cloud deploy --min-instances` / `--max-instances`** (deprecated
76
+ since 0.4.x). Use `--min-agents` / `--max-agents`. The corresponding
77
+ `min_instances` / `max_instances` fields were removed from `ScalingParams`.
78
+
79
+ - **Passing a Personal Access Token as a positional argument to `pipecat cloud auth use-pat`.**
80
+ The command now always reads the token from a secure hidden prompt (tokens on the
81
+ command line leak to shell history and process listings).
82
+
83
+ - **The deprecated `pipecat cloud organization keys delete` alias.** Use
84
+ `pipecat cloud organization keys revoke`.
85
+
86
+ ## [0.7.2] - 2026-05-29
87
+
88
+ ### Fixed
89
+
90
+ - `pcc deploy` no longer crashes with `AttributeError: 'NoneType' object has
91
+ no attribute 'get'` when a status poll hits a transient API error (e.g. a
92
+ 502 from a briefly-unavailable API pod). The poll loop now checks for the
93
+ error before reading the status payload, and transient failures (5xx,
94
+ network blips, a not-yet-visible service) are retried for up to 5
95
+ consecutive attempts before giving up. A successful poll resets that
96
+ budget, so an isolated blip no longer surfaces as a traceback or fails an
97
+ otherwise-successful deploy. Non-transient errors (4xx, auth) still abort
98
+ immediately.
99
+
8
100
  ## [0.7.1] - 2026-05-14
9
101
 
10
102
  ### Fixed
@@ -4,10 +4,10 @@ Guidance for Claude Code working in this repo.
4
4
 
5
5
  ## What this is
6
6
 
7
- **Pipecat Cloud** is the Python SDK and `pcc` CLI for deploying and managing Pipecat voice agents on Pipecat Cloud infrastructure. It ships to PyPI as `pipecatcloud`. Users install it to authenticate, build and push container images, deploy agents, manage secrets and scaling, and open sessions against running agents.
7
+ **Pipecat Cloud** is the Python SDK and CLI for deploying and managing Pipecat voice agents on Pipecat Cloud infrastructure. It ships to PyPI as `pipecatcloud`. Users authenticate, build and push container images, deploy agents, manage secrets and scaling, and open sessions against running agents. The CLI is not a standalone command — its commands are exposed through the Pipecat CLI as `pipecat cloud ...`.
8
8
 
9
9
  - Package root: `src/pipecatcloud/`
10
- - CLI entry points: `pcc` and `pipecatcloud` (also registered as a Pipecat CLI extension via the `pipecat_cli.extensions:cloud` entry point)
10
+ - CLI: registered as a Pipecat CLI extension via the `pipecat_cli.extensions:cloud` entry point (surfaced as `pipecat cloud`). There is no standalone entry point — no `[project.scripts]` and no `__main__`; the CLI runs only through the Pipecat CLI.
11
11
  - Public docs: https://docs.pipecat.daily.co
12
12
 
13
13
  ## Toolchain
@@ -73,7 +73,7 @@ src/pipecatcloud/
73
73
  session_manager.py SmallWebRTC support for non-Pipecat agents
74
74
  tests/ Pytest suite, parallel to src/
75
75
  .github/workflows/ tests.yml, format.yml, publish-pypi.yml, publish-test.yml
76
- pcc-deploy.toml Example deployment config consumed by `pcc deploy`
76
+ pcc-deploy.toml Example deployment config consumed by `pipecat cloud deploy`
77
77
  ```
78
78
 
79
79
  ## Testing conventions
@@ -81,12 +81,11 @@ pcc-deploy.toml Example deployment config consumed by `pcc deploy`
81
81
  - Layout mirrors `src/`. New tests go in `tests/test_<module>.py`.
82
82
  - `tests/conftest.py` sets `PIPECAT_CONFIG_PATH` to an isolated temp file **before imports**, pre-populated with `token = "test-token"` and `org = "test-org"`. This prevents tests from reading or clobbering real credentials. Do not bypass it.
83
83
  - Async tests use `@pytest.mark.asyncio`. Mock async calls with `unittest.mock.AsyncMock`.
84
- - `tests/test_agent_sessions.py` is **skipped in CI** because it needs real auth or heavier mocking. Run it locally if you touch session code.
85
84
  - `pytest.ini` uses `--import-mode=importlib`. Some tests manually insert `src/` onto `sys.path`, which is expected.
86
85
 
87
86
  ## CI
88
87
 
89
- - `tests.yml` runs on push to main and PRs. It currently runs `uv run pytest tests/test_docker_commands.py -v` rather than the full suite, so green CI does not guarantee the whole suite passes. Run `uv run pytest` locally before opening PRs.
88
+ - `tests.yml` runs the full suite (`uv run pytest -v`) on push to main and PRs.
90
89
  - `format.yml` runs `ruff format --diff` and `ruff check`. Both must pass.
91
90
  - `publish-pypi.yml` and `publish-test.yml` are manual dispatches that build and publish a specific git tag.
92
91
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pipecatcloud
3
- Version: 0.7.1
3
+ Version: 1.0.0
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/
@@ -34,7 +34,7 @@ Python module and CLI for interacting with [Pipecat Cloud](https://pipecat.daily
34
34
 
35
35
  ### Requirements
36
36
 
37
- - Python 3.10+
37
+ - Python 3.11+
38
38
  - Docker and a Docker repository (e.g. Docker Hub)
39
39
  - Active [Pipecat Cloud](https://pipecat.daily.co)
40
40
  account
@@ -45,31 +45,30 @@ Documentation for Pipecat Cloud is available [here](https://docs.pipecat.daily.c
45
45
 
46
46
  ### Installation
47
47
 
48
- ```shell
49
- pip install pipecatcloud
48
+ The Pipecat Cloud CLI ships as part of the [Pipecat CLI](https://github.com/pipecat-ai/pipecat-cli) — its commands are available under `pipecat cloud`. Install the Pipecat CLI:
50
49
 
51
- pcc --version
52
- pcc --help
50
+ ```shell
51
+ uv tool install pipecat-ai-cli
52
+ ```
53
53
 
54
- # Note: you can use `pcc` or `pipecatcloud` interchangeably
55
- pcc auth login
54
+ ```shell
55
+ pipecat cloud --help
56
+ pipecat cloud auth login
56
57
  ```
57
58
 
58
59
  ! All CLI commands have a `--help` flag that will display the command usage and options.
59
60
 
61
+ To use Pipecat Cloud programmatically (without the CLI), install the package directly with `uv add pipecatcloud` and see [Usage in Python scripts](#usage-in-python-scripts).
62
+
60
63
  ## Usage
61
64
 
62
65
  1. Create an account at [Pipecat Cloud](https://pipecat.daily.co)
63
66
 
64
- 2. Login to your account `pcc auth login`
65
-
66
- 3. (Optional): Clone the quickstart repo [here](https://github.com/pipecat-ai/pipecat-quickstart)
67
-
68
- 4. Build your agent `docker build --platform linux/arm64 -t your-agent-name .`
67
+ 2. Login to your account `pipecat cloud auth login`
69
68
 
70
- 5. Push your Docker image to your repository `docker push your-repository/your-agent-name:0.1`
69
+ 3. Generate secrets `pipecat cloud secrets set`
71
70
 
72
- 6. Deploy your agent `pcc deploy starter-agent your-repository/your-agent-name:0.1`
71
+ 4. Build and deploy your agent `pipecat cloud deploy`
73
72
 
74
73
  ### Usage in Python scripts
75
74
 
@@ -101,7 +100,7 @@ if __name__ == "__main__":
101
100
 
102
101
  ### SSL certificate errors on macOS
103
102
 
104
- If `pcc auth login` fails with an SSL certificate verification error, your Python
103
+ If `pipecat cloud auth login` fails with an SSL certificate verification error, your Python
105
104
  installation may not have access to the macOS system certificate store. This is
106
105
  common with Python installed via pyenv, conda, or the python.org installer.
107
106
 
@@ -11,7 +11,7 @@ Python module and CLI for interacting with [Pipecat Cloud](https://pipecat.daily
11
11
 
12
12
  ### Requirements
13
13
 
14
- - Python 3.10+
14
+ - Python 3.11+
15
15
  - Docker and a Docker repository (e.g. Docker Hub)
16
16
  - Active [Pipecat Cloud](https://pipecat.daily.co)
17
17
  account
@@ -22,31 +22,30 @@ Documentation for Pipecat Cloud is available [here](https://docs.pipecat.daily.c
22
22
 
23
23
  ### Installation
24
24
 
25
- ```shell
26
- pip install pipecatcloud
25
+ The Pipecat Cloud CLI ships as part of the [Pipecat CLI](https://github.com/pipecat-ai/pipecat-cli) — its commands are available under `pipecat cloud`. Install the Pipecat CLI:
27
26
 
28
- pcc --version
29
- pcc --help
27
+ ```shell
28
+ uv tool install pipecat-ai-cli
29
+ ```
30
30
 
31
- # Note: you can use `pcc` or `pipecatcloud` interchangeably
32
- pcc auth login
31
+ ```shell
32
+ pipecat cloud --help
33
+ pipecat cloud auth login
33
34
  ```
34
35
 
35
36
  ! All CLI commands have a `--help` flag that will display the command usage and options.
36
37
 
38
+ To use Pipecat Cloud programmatically (without the CLI), install the package directly with `uv add pipecatcloud` and see [Usage in Python scripts](#usage-in-python-scripts).
39
+
37
40
  ## Usage
38
41
 
39
42
  1. Create an account at [Pipecat Cloud](https://pipecat.daily.co)
40
43
 
41
- 2. Login to your account `pcc auth login`
42
-
43
- 3. (Optional): Clone the quickstart repo [here](https://github.com/pipecat-ai/pipecat-quickstart)
44
-
45
- 4. Build your agent `docker build --platform linux/arm64 -t your-agent-name .`
44
+ 2. Login to your account `pipecat cloud auth login`
46
45
 
47
- 5. Push your Docker image to your repository `docker push your-repository/your-agent-name:0.1`
46
+ 3. Generate secrets `pipecat cloud secrets set`
48
47
 
49
- 6. Deploy your agent `pcc deploy starter-agent your-repository/your-agent-name:0.1`
48
+ 4. Build and deploy your agent `pipecat cloud deploy`
50
49
 
51
50
  ### Usage in Python scripts
52
51
 
@@ -78,7 +77,7 @@ if __name__ == "__main__":
78
77
 
79
78
  ### SSL certificate errors on macOS
80
79
 
81
- If `pcc auth login` fails with an SSL certificate verification error, your Python
80
+ If `pipecat cloud auth login` fails with an SSL certificate verification error, your Python
82
81
  installation may not have access to the macOS system certificate store. This is
83
82
  common with Python installed via pyenv, conda, or the python.org installer.
84
83
 
@@ -19,12 +19,19 @@ dependencies = [
19
19
  "typer>=0.20.0,<1",
20
20
  "synchronicity>=0.11,<1.0.0",
21
21
  "toml~=0.10.2",
22
- "questionary~=2.1.0"
22
+ "questionary~=2.1.0",
23
23
  ]
24
24
 
25
25
  [project.optional-dependencies]
26
+ # The agent session-argument types (pipecatcloud.agent) subclass pipecat-ai's
27
+ # runner argument types. pipecat-ai is optional so the SDK and CLI surface stay
28
+ # lightweight — e.g. so the pipecat-base image doesn't pull pipecat-ai into its
29
+ # layer (the bot provides it). Floor is 1.0.0; `session_id` on the base
30
+ # RunnerArguments came later (v1.2.0) but is supplied by the SessionArguments
31
+ # mixin for pipecat-ai in [1.0.0, 1.2.0).
26
32
  pipecat = ["pipecat-ai>=1.0.0"]
27
33
 
34
+
28
35
  [dependency-groups]
29
36
  dev = [
30
37
  "build~=1.4.0",
@@ -36,12 +43,10 @@ dev = [
36
43
  "ruff>=0.12.11,<1",
37
44
  "setuptools~=78.1.1",
38
45
  "setuptools_scm~=8.3.1",
46
+ # Needed to import/test pipecatcloud.agent (the optional pipecat surface).
47
+ "pipecat-ai>=1.0.0",
39
48
  ]
40
49
 
41
- [project.scripts]
42
- pcc = "pipecatcloud.__main__:main"
43
- pipecatcloud = "pipecatcloud.__main__:main"
44
-
45
50
  [project.entry-points."pipecat_cli.extensions"]
46
51
  cloud = "pipecatcloud.cli.entry_point:entrypoint_cli_typer"
47
52
 
@@ -9,13 +9,6 @@ import sys
9
9
 
10
10
  from loguru import logger
11
11
 
12
- from pipecatcloud.agent import (
13
- DailySessionArguments,
14
- PipecatSessionArguments,
15
- SessionArguments,
16
- SmallWebRTCRunnerArguments,
17
- WebSocketSessionArguments,
18
- )
19
12
  from pipecatcloud.exception import (
20
13
  AgentNotHealthyError,
21
14
  AgentStartError,
@@ -32,12 +25,38 @@ logger.remove()
32
25
  logger.add(sys.stderr, level=str(os.getenv("PCC_LOG_LEVEL", "INFO")))
33
26
 
34
27
 
28
+ # The agent session-argument types subclass pipecat-ai's runner argument types,
29
+ # so importing them pulls in pipecat-ai (an optional dependency). Resolve them
30
+ # lazily (PEP 562) so plain `import pipecatcloud` — the SDK and CLI surface — does
31
+ # not require pipecat-ai. Accessing one of these names imports pipecatcloud.agent,
32
+ # which raises a clear ImportError if pipecat-ai is not installed.
33
+ _LAZY_AGENT_EXPORTS = (
34
+ "DailySessionArguments",
35
+ "PipecatSessionArguments",
36
+ "SessionArguments",
37
+ "SmallWebRTCSessionArguments",
38
+ "WebSocketSessionArguments",
39
+ )
40
+
41
+
42
+ def __getattr__(name: str):
43
+ if name in _LAZY_AGENT_EXPORTS:
44
+ from pipecatcloud import agent
45
+
46
+ return getattr(agent, name)
47
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
48
+
49
+
50
+ def __dir__():
51
+ return sorted(list(globals()) + list(_LAZY_AGENT_EXPORTS))
52
+
53
+
35
54
  __all__ = [
36
55
  # Agent classes
37
56
  "DailySessionArguments",
38
57
  "PipecatSessionArguments",
39
58
  "SessionArguments",
40
- "SmallWebRTCRunnerArguments",
59
+ "SmallWebRTCSessionArguments",
41
60
  "WebSocketSessionArguments",
42
61
  # Session classes
43
62
  "Session",
@@ -13,6 +13,20 @@ from rich.panel import Panel
13
13
  from pipecatcloud.cli import PANEL_TITLE_ERROR, PANEL_TITLE_SUCCESS, PIPECAT_CLI_NAME
14
14
 
15
15
 
16
+ def format_cents(cents: int | None) -> str:
17
+ """Render a cents value as a USD dollar string (e.g. 1234 -> "$12.34").
18
+
19
+ Uses integer arithmetic so the rendered value is exact for any in-range
20
+ integer, even values float-division would round (e.g. very large cent
21
+ counts where `cents / 100` loses precision).
22
+ """
23
+ if cents is None:
24
+ return "no limit"
25
+ sign = "-" if cents < 0 else ""
26
+ abs_cents = abs(cents)
27
+ return f"{sign}${abs_cents // 100}.{abs_cents % 100:02d}"
28
+
29
+
16
30
  class PipecatConsole(Console):
17
31
  def success(
18
32
  self,
@@ -90,6 +104,11 @@ class PipecatConsole(Console):
90
104
  error_message = str(error_code) if error_code else DEFAULT_ERROR_MESSAGE
91
105
  code = None
92
106
 
107
+ if code == "SPEND_LIMIT_REACHED":
108
+ # Safe to pass through: code is only set when error_code is a dict.
109
+ self._spend_limit_reached(error_code) # type: ignore[arg-type]
110
+ return
111
+
93
112
  if not error_message:
94
113
  hide_subtitle = True
95
114
 
@@ -106,6 +125,48 @@ class PipecatConsole(Console):
106
125
  )
107
126
  )
108
127
 
128
+ def _spend_limit_reached(self, error: dict):
129
+ """Render the wrapped remediation message for HTTP 402 SPEND_LIMIT_REACHED.
130
+
131
+ Falls back gracefully if the error body omits the spend fields: in that
132
+ case we render the remediation message without the usage line.
133
+ """
134
+ from pipecatcloud.config import config as base_config
135
+
136
+ current = error.get("currentSpendCents")
137
+ limit = error.get("limitCents")
138
+
139
+ if current is not None and limit is not None:
140
+ usage_line = (
141
+ f"Your organization has reached its spend limit "
142
+ f"({format_cents(current)} of {format_cents(limit)} used in this billing period)."
143
+ )
144
+ else:
145
+ usage_line = (
146
+ "Your organization has reached its spend limit for the current billing period."
147
+ )
148
+
149
+ # Fall back to the documented default if the host is unset or empty,
150
+ # so the rendered link is never `[link=][/link]` or `[link=None]None[/link]`.
151
+ dashboard = base_config.get("dashboard_host") or "https://pipecat.daily.co"
152
+ body = (
153
+ f"{usage_line}\n"
154
+ "New sessions are being rejected. In-flight sessions continue to run.\n\n"
155
+ "To unblock new sessions:\n"
156
+ f" [bold cyan]{PIPECAT_CLI_NAME} spend-limit set <new amount>[/bold cyan]\n"
157
+ f" [bold cyan]{PIPECAT_CLI_NAME} spend-limit clear[/bold cyan]\n\n"
158
+ f"Or visit [link={dashboard}]{dashboard}[/link]"
159
+ )
160
+
161
+ self.print(
162
+ Panel(
163
+ body,
164
+ title=f"[bold red]{PANEL_TITLE_ERROR} - Spend limit reached (402)[/bold red]",
165
+ title_align="left",
166
+ border_style="red",
167
+ )
168
+ )
169
+
109
170
 
110
171
  console = PipecatConsole()
111
172
 
@@ -266,21 +266,8 @@ def interpret_deployment_status(
266
266
  class ScalingParams:
267
267
  min_agents: int | None = 0
268
268
  max_agents: int | None = None
269
- # @deprecated
270
- min_instances: int | None = field(default=None, metadata={"deprecated": True})
271
- # @deprecated
272
- max_instances: int | None = field(default=None, metadata={"deprecated": True})
273
269
 
274
270
  def __attrs_post_init__(self):
275
- # Handle deprecated fields
276
- if self.min_instances is not None:
277
- logger.warning("min_instances is deprecated, use min_agents instead")
278
- self.min_agents = self.min_instances
279
-
280
- if self.max_instances is not None:
281
- logger.warning("max_instances is deprecated, use max_agents instead")
282
- self.max_agents = self.max_instances
283
-
284
271
  # Validation
285
272
  if self.min_agents is not None:
286
273
  if self.min_agents < 0:
@@ -339,7 +326,6 @@ class DeployConfigParams:
339
326
  secret_set: str | None = None
340
327
  region: str | None = None
341
328
  scaling: ScalingParams = ScalingParams()
342
- enable_krisp: bool = False
343
329
  docker_config: dict = field(factory=dict)
344
330
  build_config: BuildConfig = field(factory=BuildConfig) # Cloud build configuration
345
331
  agent_profile: str | None = None
@@ -366,7 +352,6 @@ class DeployConfigParams:
366
352
  "secret_set": self.secret_set,
367
353
  "region": self.region,
368
354
  "scaling": self.scaling.to_dict() if self.scaling else None,
369
- "enable_krisp": self.enable_krisp,
370
355
  "docker_config": self.docker_config,
371
356
  "build_config": self.build_config.to_dict() if self.build_config else None,
372
357
  "agent_profile": self.agent_profile,
@@ -409,16 +394,8 @@ def load_deploy_config_file() -> DeployConfigParams | None:
409
394
  exclude_patterns=exclude_data.get("patterns", []),
410
395
  )
411
396
 
412
- # Create DeployConfigParams with validated data
413
- validated_config = DeployConfigParams(
414
- **config_data,
415
- scaling=scaling_params,
416
- docker_config=docker_data,
417
- build_config=build_config,
418
- krisp_viva=krisp_viva_config,
419
- )
420
-
421
- # Check for unexpected keys
397
+ # Check for unexpected keys before constructing the config, so users get a clear
398
+ # message instead of a raw constructor TypeError.
422
399
  expected_keys = {
423
400
  "agent_name",
424
401
  "image",
@@ -427,7 +404,6 @@ def load_deploy_config_file() -> DeployConfigParams | None:
427
404
  "secret_set",
428
405
  "region",
429
406
  "scaling",
430
- "enable_krisp",
431
407
  "docker",
432
408
  "build",
433
409
  "agent_profile",
@@ -435,10 +411,26 @@ def load_deploy_config_file() -> DeployConfigParams | None:
435
411
  "websocket_auth",
436
412
  "max_session_duration",
437
413
  }
414
+
415
+ # TODO: Remove this enable_krisp migration hint in the 2.0.0 release.
416
+ if "enable_krisp" in config_data:
417
+ raise ConfigFileError(
418
+ "'enable_krisp' is no longer supported. Krisp is now configured via the "
419
+ "[krisp_viva] section in pcc-deploy.toml. Remove 'enable_krisp' from your config."
420
+ )
438
421
  unexpected_keys = set(config_data.keys()) - expected_keys
439
422
  if unexpected_keys:
440
423
  raise ConfigFileError(f"Unexpected keys in config file: {unexpected_keys}")
441
424
 
425
+ # Create DeployConfigParams with validated data
426
+ validated_config = DeployConfigParams(
427
+ **config_data,
428
+ scaling=scaling_params,
429
+ docker_config=docker_data,
430
+ build_config=build_config,
431
+ krisp_viva=krisp_viva_config,
432
+ )
433
+
442
434
  return validated_config
443
435
 
444
436
  except Exception as e:
@@ -0,0 +1,85 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
7
+ """Agent session argument types.
8
+
9
+ These are the argument types passed to a bot's ``bot()`` entry point. Each is a
10
+ thin subclass of the matching pipecat-ai runner argument type
11
+ (``pipecat.runner.types.*RunnerArguments``), so they interoperate with pipecat's
12
+ runner machinery (``create_transport``, ``isinstance`` checks) while giving
13
+ Pipecat Cloud a stable, branded session-argument API.
14
+
15
+ These types require **pipecat-ai** (>= 1.0.0). pipecat-ai is an optional
16
+ dependency of pipecatcloud (the SDK and CLI do not need it), so a bot environment
17
+ must provide it — install with ``pip install "pipecatcloud[pipecat]"`` or bring
18
+ your own ``pipecat-ai``. Importing this module without pipecat-ai raises a clear
19
+ ``ImportError``.
20
+ """
21
+
22
+ from dataclasses import dataclass
23
+
24
+ try:
25
+ from pipecat.runner.types import (
26
+ DailyRunnerArguments,
27
+ RunnerArguments,
28
+ SmallWebRTCRunnerArguments,
29
+ WebSocketRunnerArguments,
30
+ )
31
+ except ImportError as e: # pragma: no cover - exercised only without pipecat-ai
32
+ raise ImportError(
33
+ "pipecatcloud's agent session-argument types require pipecat-ai>=1.0.0. "
34
+ 'Install it with `pip install "pipecatcloud[pipecat]"`, or add pipecat-ai '
35
+ "to your environment."
36
+ ) from e
37
+
38
+
39
+ @dataclass
40
+ class SessionArguments:
41
+ """Base class / marker for Pipecat Cloud agent session arguments.
42
+
43
+ The arguments are received by the bot() entry point.
44
+
45
+ Parameters:
46
+ session_id (str | None): The unique identifier for the session, used to
47
+ track it across requests.
48
+ """
49
+
50
+ # ``session_id`` is intentionally declared here as a compatibility shim:
51
+ # pipecat-ai only added ``session_id`` to the base ``RunnerArguments`` in
52
+ # v1.2.0. For pipecat-ai in the [1.0.0, 1.2.0) range, this mixin supplies
53
+ # ``session_id``. When pipecat-ai *does* define it on the base, that field
54
+ # overrides this one because ``RunnerArguments`` appears later than
55
+ # ``SessionArguments`` in the MRO of the subclasses below. That is why every
56
+ # subclass must list the ``*RunnerArguments`` base FIRST — e.g.
57
+ # ``(DailyRunnerArguments, SessionArguments)``. Do not reorder the bases.
58
+ # (No default here on purpose: giving it one would order a defaulted field
59
+ # before ``room_url`` on older pipecat-ai and raise "non-default argument
60
+ # follows default argument".)
61
+ session_id: str | None
62
+
63
+
64
+ @dataclass
65
+ class PipecatSessionArguments(RunnerArguments, SessionArguments):
66
+ """Standard Pipecat Cloud agent session arguments (no specific transport).
67
+
68
+ Used for HTTP activations that did not request a Daily room — for example the
69
+ room-less SmallWebRTC flow, where the WebRTC connection arrives separately.
70
+ """
71
+
72
+
73
+ @dataclass
74
+ class DailySessionArguments(DailyRunnerArguments, SessionArguments):
75
+ """Daily-based agent session arguments."""
76
+
77
+
78
+ @dataclass
79
+ class WebSocketSessionArguments(WebSocketRunnerArguments, SessionArguments):
80
+ """WebSocket-based agent session arguments."""
81
+
82
+
83
+ @dataclass
84
+ class SmallWebRTCSessionArguments(SmallWebRTCRunnerArguments, SessionArguments):
85
+ """SmallWebRTCTransport-based agent session arguments."""