pipecatcloud 0.1.0__tar.gz → 0.1.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.1.0 → pipecatcloud-0.1.2}/.github/workflows/publish-pypi.yml +10 -3
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/.github/workflows/publish-test.yml +14 -6
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/CHANGELOG.md +25 -3
- {pipecatcloud-0.1.0/src/pipecatcloud.egg-info → pipecatcloud-0.1.2}/PKG-INFO +2 -2
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/README.md +1 -1
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/pyproject.toml +1 -1
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/__init__.py +7 -2
- pipecatcloud-0.1.2/src/pipecatcloud/agent.py +52 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/commands/agent.py +17 -7
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/commands/deploy.py +51 -18
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/config.py +18 -8
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/exception.py +7 -1
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2/src/pipecatcloud.egg-info}/PKG-INFO +2 -2
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud.egg-info/SOURCES.txt +1 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/.github/workflows/python-publish.yml +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/.gitignore +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/LICENSE +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/dev-requirements.txt +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/pipecat-cloud.png +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/setup.cfg +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/__main__.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/__version__.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/_utils/__init__.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/_utils/async_utils.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/_utils/auth_utils.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/_utils/console_utils.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/_utils/deploy_utils.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/_utils/local_runner.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/api.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/__init__.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/api.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/commands/__init__.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/commands/auth.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/commands/init.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/commands/organizations.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/commands/run.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/commands/secrets.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/cli/entry_point.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/config.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud/session.py +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud.egg-info/requires.txt +0 -0
- {pipecatcloud-0.1.0 → pipecatcloud-0.1.2}/src/pipecatcloud.egg-info/top_level.txt +0 -0
|
@@ -45,12 +45,19 @@ jobs:
|
|
|
45
45
|
- name: Build package
|
|
46
46
|
run: python -m build
|
|
47
47
|
|
|
48
|
-
- name:
|
|
48
|
+
- name: Check and create release tag if needed
|
|
49
49
|
run: |
|
|
50
50
|
git config --local user.email "action@github.com"
|
|
51
51
|
git config --local user.name "GitHub Action"
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
|
|
53
|
+
# Check if tag already exists remotely
|
|
54
|
+
if git ls-remote --tags origin | grep -q "refs/tags/v${{ github.event.inputs.version }}"; then
|
|
55
|
+
echo "Tag v${{ github.event.inputs.version }} already exists, skipping tag creation"
|
|
56
|
+
else
|
|
57
|
+
echo "Creating new tag v${{ github.event.inputs.version }}"
|
|
58
|
+
git tag -a "v${{ github.event.inputs.version }}" -m "Version ${{ github.event.inputs.version }}"
|
|
59
|
+
git push origin "v${{ github.event.inputs.version }}"
|
|
60
|
+
fi
|
|
54
61
|
|
|
55
62
|
- name: Publish to PyPI
|
|
56
63
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -15,8 +15,8 @@ jobs:
|
|
|
15
15
|
name: pypi
|
|
16
16
|
url: https://test.pypi.org/project/pipecat-cloud
|
|
17
17
|
permissions:
|
|
18
|
-
id-token: write
|
|
19
|
-
contents: write
|
|
18
|
+
id-token: write
|
|
19
|
+
contents: write
|
|
20
20
|
|
|
21
21
|
steps:
|
|
22
22
|
- name: Checkout code
|
|
@@ -45,15 +45,23 @@ jobs:
|
|
|
45
45
|
- name: Build package
|
|
46
46
|
run: python -m build
|
|
47
47
|
|
|
48
|
-
- name:
|
|
48
|
+
- name: Check and create release tag if needed
|
|
49
49
|
run: |
|
|
50
50
|
git config --local user.email "action@github.com"
|
|
51
51
|
git config --local user.name "GitHub Action"
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
|
|
53
|
+
# Check if tag already exists remotely
|
|
54
|
+
if git ls-remote --tags origin | grep -q "refs/tags/v${{ github.event.inputs.version }}"; then
|
|
55
|
+
echo "Tag v${{ github.event.inputs.version }} already exists, skipping tag creation"
|
|
56
|
+
else
|
|
57
|
+
echo "Creating new tag v${{ github.event.inputs.version }}"
|
|
58
|
+
git tag -a "v${{ github.event.inputs.version }}" -m "Version ${{ github.event.inputs.version }}"
|
|
59
|
+
git push origin "v${{ github.event.inputs.version }}"
|
|
60
|
+
fi
|
|
54
61
|
|
|
55
62
|
- name: Publish to PyPI
|
|
56
63
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
57
64
|
with:
|
|
65
|
+
repository-url: https://test.pypi.org/legacy/
|
|
58
66
|
verbose: true
|
|
59
|
-
print-hash: true
|
|
67
|
+
print-hash: true
|
|
@@ -5,13 +5,35 @@ 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]
|
|
9
|
+
|
|
10
|
+
## [0.1.2] - 2025-03-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `agent.py` data classes for use in base images, providing guidance on params
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Lookup issue when passing an image pull secret to the `deploy` command
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Change the of deploy checks from 30 to 18, reducing the overall time for a
|
|
23
|
+
deployment.
|
|
24
|
+
|
|
25
|
+
- Added a `--format / -f` option for `agent logs`. Options are `TEXT` and
|
|
26
|
+
`JSON`.
|
|
27
|
+
|
|
28
|
+
- Improved error messaging for `ConfigError` to improve debugging.
|
|
29
|
+
|
|
8
30
|
## [0.1.0] - 2025-03-05
|
|
9
31
|
|
|
10
|
-
- `pipecatcloud.toml` moved to `$HOME/.config/pipecatcloud/pipecatcloud.toml
|
|
32
|
+
- `pipecatcloud.toml` moved to `$HOME/.config/pipecatcloud/pipecatcloud.toml`.
|
|
11
33
|
|
|
12
34
|
### Added
|
|
13
35
|
|
|
14
|
-
- `pcc auth whoami` now shows the namespace Daily API key for convenience
|
|
36
|
+
- `pcc auth whoami` now shows the namespace Daily API key for convenience.
|
|
15
37
|
|
|
16
38
|
## [0.0.11] - 2025-03-04
|
|
17
39
|
|
|
@@ -83,4 +105,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
83
105
|
- Fixed a bug where `pcc-deploy.toml` files were required to be present.
|
|
84
106
|
|
|
85
107
|
- `deploy` command now correctly passes the secret set to the deployment from
|
|
86
|
-
the `pcc-deploy.toml` file.
|
|
108
|
+
the `pcc-deploy.toml` file.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: pipecatcloud
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.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/
|
|
@@ -19,7 +19,7 @@ Requires-Dist: toml~=0.10.2
|
|
|
19
19
|
Requires-Dist: questionary~=2.1.0
|
|
20
20
|
|
|
21
21
|
<h1><div align="center">
|
|
22
|
-
<img alt="pipecat cloud" width="500px" height="auto" src="
|
|
22
|
+
<img alt="pipecat cloud" width="500px" height="auto" src="https://raw.githubusercontent.com/daily-co/pipecat-cloud/main/pipecat-cloud.png">
|
|
23
23
|
</div></h1>
|
|
24
24
|
|
|
25
25
|
[](https://docs.pipecat.daily.co)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<h1><div align="center">
|
|
2
|
-
<img alt="pipecat cloud" width="500px" height="auto" src="
|
|
2
|
+
<img alt="pipecat cloud" width="500px" height="auto" src="https://raw.githubusercontent.com/daily-co/pipecat-cloud/main/pipecat-cloud.png">
|
|
3
3
|
</div></h1>
|
|
4
4
|
|
|
5
5
|
[](https://docs.pipecat.daily.co)
|
|
@@ -9,7 +9,8 @@ import sys
|
|
|
9
9
|
|
|
10
10
|
from loguru import logger
|
|
11
11
|
|
|
12
|
-
from .
|
|
12
|
+
from pipecatcloud.agent import DailySessionArguments, SessionArguments, WebSocketSessionArguments
|
|
13
|
+
from pipecatcloud.exception import (
|
|
13
14
|
AgentNotHealthyError,
|
|
14
15
|
AgentStartError,
|
|
15
16
|
AuthError,
|
|
@@ -18,13 +19,17 @@ from .exception import (
|
|
|
18
19
|
Error,
|
|
19
20
|
InvalidError,
|
|
20
21
|
)
|
|
21
|
-
from .session import Session, SessionParams
|
|
22
|
+
from pipecatcloud.session import Session, SessionParams
|
|
22
23
|
|
|
23
24
|
logger.remove()
|
|
24
25
|
logger.add(sys.stderr, level=str(os.getenv("PCC_LOG_LEVEL", "INFO")))
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
__all__ = [
|
|
29
|
+
# Agent classes
|
|
30
|
+
"SessionArguments",
|
|
31
|
+
"DailySessionArguments",
|
|
32
|
+
"WebSocketSessionArguments",
|
|
28
33
|
# Session classes
|
|
29
34
|
"Session",
|
|
30
35
|
"SessionParams",
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# SPDX-License-Identifier: BSD 2-Clause License
|
|
5
5
|
#
|
|
6
6
|
|
|
7
|
+
import json
|
|
7
8
|
from enum import Enum
|
|
8
9
|
|
|
9
10
|
import aiohttp
|
|
@@ -220,6 +221,11 @@ async def scale():
|
|
|
220
221
|
console.error("Not implemented")
|
|
221
222
|
|
|
222
223
|
|
|
224
|
+
class LogFormat(str, Enum):
|
|
225
|
+
TEXT = "TEXT"
|
|
226
|
+
JSON = "JSON"
|
|
227
|
+
|
|
228
|
+
|
|
223
229
|
class LogLevel(str, Enum):
|
|
224
230
|
DEBUG = "DEBUG"
|
|
225
231
|
INFO = "INFO"
|
|
@@ -229,8 +235,8 @@ class LogLevel(str, Enum):
|
|
|
229
235
|
|
|
230
236
|
|
|
231
237
|
class LogLevelColors(str, Enum):
|
|
232
|
-
DEBUG = "
|
|
233
|
-
INFO = "
|
|
238
|
+
DEBUG = "blue"
|
|
239
|
+
INFO = "green"
|
|
234
240
|
WARNING = "yellow"
|
|
235
241
|
ERROR = "red"
|
|
236
242
|
CRITICAL = "bold red"
|
|
@@ -245,6 +251,7 @@ async def logs(
|
|
|
245
251
|
None, "--organization", "-o", help="Organization to get status of agent for"
|
|
246
252
|
),
|
|
247
253
|
level: LogLevel = typer.Option(None, "--level", "-l", help="Level of logs to get"),
|
|
254
|
+
format: LogFormat = typer.Option(LogFormat.TEXT, "--format", "-f", help="Logs format"),
|
|
248
255
|
limit: int = typer.Option(100, "--limit", "-n", help="Number of logs to get"),
|
|
249
256
|
):
|
|
250
257
|
org = organization or config.get("org")
|
|
@@ -271,10 +278,14 @@ async def logs(
|
|
|
271
278
|
# filter out any messages that do not match our log level
|
|
272
279
|
if level and severity.value != level.value:
|
|
273
280
|
continue
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
281
|
+
|
|
282
|
+
if format == LogFormat.TEXT:
|
|
283
|
+
color = getattr(LogLevelColors, severity, LogLevelColors.DEBUG).value
|
|
284
|
+
console.print(Text(timestamp, style="bold dim"), end=" ")
|
|
285
|
+
console.print(Text(l.get("log", ""), style=color))
|
|
286
|
+
elif format == LogFormat.JSON:
|
|
287
|
+
line = {"timestamp": timestamp, "log": l.get("log", "")}
|
|
288
|
+
console.print(Text(json.dumps(line, ensure_ascii=False), style="gray"))
|
|
278
289
|
|
|
279
290
|
|
|
280
291
|
@agent_cli.command(name="delete", help="Delete an agent.")
|
|
@@ -349,7 +360,6 @@ async def deployments(
|
|
|
349
360
|
response.raise_for_status()
|
|
350
361
|
|
|
351
362
|
data = await response.json()
|
|
352
|
-
print(data)
|
|
353
363
|
|
|
354
364
|
table = Table(
|
|
355
365
|
show_header=True,
|
|
@@ -25,7 +25,7 @@ from pipecatcloud.cli import PIPECAT_CLI_NAME
|
|
|
25
25
|
from pipecatcloud.cli.api import API
|
|
26
26
|
from pipecatcloud.cli.config import config
|
|
27
27
|
|
|
28
|
-
MAX_ALIVE_CHECKS =
|
|
28
|
+
MAX_ALIVE_CHECKS = 18
|
|
29
29
|
ALIVE_CHECK_SLEEP = 5
|
|
30
30
|
|
|
31
31
|
# ----- Command
|
|
@@ -36,7 +36,8 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
|
|
|
36
36
|
|
|
37
37
|
# Check for an existing deployment with this agent name
|
|
38
38
|
with Live(
|
|
39
|
-
console.status("[dim]Checking for existing agent deployment...[/dim]", spinner="dots"),
|
|
39
|
+
console.status("[dim]Checking for existing agent deployment...[/dim]", spinner="dots"),
|
|
40
|
+
transient=True,
|
|
40
41
|
) as live:
|
|
41
42
|
data, error = await API.agent(agent_name=params.agent_name, org=org, live=live)
|
|
42
43
|
|
|
@@ -57,7 +58,7 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
|
|
|
57
58
|
return typer.Exit()
|
|
58
59
|
|
|
59
60
|
# Start the deployment process
|
|
60
|
-
with Live(console.status("[dim]Preparing deployment...", spinner="dots")) as live:
|
|
61
|
+
with Live(console.status("[dim]Preparing deployment...", spinner="dots"), transient=True) as live:
|
|
61
62
|
"""
|
|
62
63
|
# 1. Check that provided secret set exists
|
|
63
64
|
"""
|
|
@@ -93,7 +94,7 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
|
|
|
93
94
|
)
|
|
94
95
|
|
|
95
96
|
if error:
|
|
96
|
-
if error == 400:
|
|
97
|
+
if error.get("code") == "400":
|
|
97
98
|
creds_exist = True
|
|
98
99
|
else:
|
|
99
100
|
API.print_error()
|
|
@@ -134,9 +135,13 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
|
|
|
134
135
|
is_ready = False
|
|
135
136
|
checks_performed = 0
|
|
136
137
|
|
|
138
|
+
console.print(
|
|
139
|
+
f"[bold cyan]{'Updating' if existing_agent else 'Pushing'}[/bold cyan] deployment for agent '{params.agent_name}'")
|
|
140
|
+
|
|
137
141
|
# Create a simple spinner for the polling phase
|
|
142
|
+
deployment_status_message = "[dim]Waiting for deployment to become ready...[/dim]"
|
|
138
143
|
with console.status(
|
|
139
|
-
|
|
144
|
+
deployment_status_message, spinner="bouncingBar"
|
|
140
145
|
) as status:
|
|
141
146
|
try:
|
|
142
147
|
while checks_performed < MAX_ALIVE_CHECKS:
|
|
@@ -153,6 +158,7 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
|
|
|
153
158
|
# Update deployment ID if received (silently)
|
|
154
159
|
if not active_deployment_id and agent_status.get("activeDeploymentId"):
|
|
155
160
|
active_deployment_id = agent_status["activeDeploymentId"]
|
|
161
|
+
deployment_status_message = f"[dim]Waiting for deployment to become ready (deployment ID: {active_deployment_id})...[/dim]"
|
|
156
162
|
|
|
157
163
|
# Check if deployment is ready
|
|
158
164
|
if agent_status.get("ready"):
|
|
@@ -176,17 +182,37 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
|
|
|
176
182
|
console.error("Deployment failed with the above error")
|
|
177
183
|
return typer.Exit()
|
|
178
184
|
|
|
185
|
+
# check for org secret
|
|
186
|
+
default_public_api_key = config.get("default_public_key")
|
|
187
|
+
|
|
179
188
|
if is_ready:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
189
|
+
if not default_public_api_key:
|
|
190
|
+
console.print(
|
|
191
|
+
Panel(
|
|
192
|
+
f"No public API key provided. Please provide a public API key using the --api-key flag or set a default using [bold cyan]{PIPECAT_CLI_NAME} organizations keys use[/bold cyan].\n\n"
|
|
193
|
+
f"If you have not yet created a public API key, you can do so by running [bold cyan]{PIPECAT_CLI_NAME} organizations keys create[/bold cyan].\n\n"
|
|
194
|
+
f"Then...\n\n"
|
|
195
|
+
f"[dim]Start a session with your new agent by running:\n[/dim]"
|
|
196
|
+
f"[bold]`{PIPECAT_CLI_NAME} agent start {params.agent_name}`[/bold]",
|
|
197
|
+
title="Public API Key Required",
|
|
198
|
+
title_align="left",
|
|
199
|
+
border_style="yellow",
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
return typer.Exit(1)
|
|
204
|
+
else:
|
|
205
|
+
console.success(
|
|
206
|
+
f"Agent deployment [bold]'{params.agent_name}'[/bold] is ready\n\n"
|
|
207
|
+
f"[dim]Start a session with your new agent by running:\n[/dim]"
|
|
208
|
+
f"[bold]`{PIPECAT_CLI_NAME} agent start {params.agent_name}`[/bold]",
|
|
209
|
+
title_extra=f"{'Update' if existing_agent else 'Deployment'} complete",
|
|
210
|
+
)
|
|
186
211
|
else:
|
|
187
212
|
console.error(
|
|
188
213
|
f"Deployment did not enter ready state within {MAX_ALIVE_CHECKS * ALIVE_CHECK_SLEEP} seconds. "
|
|
189
|
-
f"Please check logs with `{PIPECAT_CLI_NAME} agent logs {params.agent_name}`"
|
|
214
|
+
f"Please check logs with `{PIPECAT_CLI_NAME} agent logs {params.agent_name}`"
|
|
215
|
+
)
|
|
190
216
|
|
|
191
217
|
return typer.Exit()
|
|
192
218
|
|
|
@@ -299,17 +325,24 @@ def create_deploy_command(app: typer.Typer):
|
|
|
299
325
|
(f"[bold white]Agent name:[/bold white] [green]{partial_config.agent_name}[/green]"),
|
|
300
326
|
(f"[bold white]Image:[/bold white] [green]{partial_config.image}[/green]"),
|
|
301
327
|
(f"[bold white]Organization:[/bold white] [green]{org}[/green]"),
|
|
302
|
-
(
|
|
303
|
-
|
|
328
|
+
(
|
|
329
|
+
f"[bold white]Secret set:[/bold white] {'[dim]None[/dim]' if not partial_config.secret_set else '[green] '+ partial_config.secret_set + '[/green]'}"
|
|
330
|
+
),
|
|
331
|
+
(
|
|
332
|
+
f"[bold white]Image pull secret:[/bold white] {'[dim]None[/dim]' if not partial_config.image_credentials else '[green]' + partial_config.image_credentials + '[/green]'}"
|
|
333
|
+
),
|
|
304
334
|
"\n[dim]Scaling configuration:[/dim]",
|
|
305
335
|
table,
|
|
306
|
-
*
|
|
307
|
-
|
|
308
|
-
|
|
336
|
+
*(
|
|
337
|
+
[]
|
|
338
|
+
if partial_config.scaling.min_instances
|
|
339
|
+
else [
|
|
309
340
|
Text(
|
|
310
341
|
"Note: Deploying with 0 minimum instances may result in cold starts",
|
|
311
342
|
style="red",
|
|
312
|
-
)
|
|
343
|
+
)
|
|
344
|
+
]
|
|
345
|
+
),
|
|
313
346
|
)
|
|
314
347
|
|
|
315
348
|
console.print(
|
|
@@ -27,22 +27,26 @@ deploy_config_path: str = os.environ.get("PIPECAT_DEPLOY_CONFIG_PATH") or os.pat
|
|
|
27
27
|
|
|
28
28
|
def _read_user_config():
|
|
29
29
|
config_data = {}
|
|
30
|
+
config_problem = ""
|
|
31
|
+
|
|
30
32
|
if os.path.exists(user_config_path):
|
|
31
33
|
try:
|
|
32
34
|
with open(user_config_path) as f:
|
|
33
35
|
config_data = toml.load(f)
|
|
36
|
+
except toml.TomlDecodeError as exc:
|
|
37
|
+
config_problem = f"Invalid TOML syntax in config file: {exc}"
|
|
38
|
+
except PermissionError:
|
|
39
|
+
config_problem = f"Permission denied when reading config file: {user_config_path}"
|
|
40
|
+
except IOError as exc:
|
|
41
|
+
config_problem = f"I/O error when reading config file: {exc}"
|
|
34
42
|
except Exception as exc:
|
|
35
|
-
config_problem =
|
|
43
|
+
config_problem = f"Error reading config file: {exc}"
|
|
36
44
|
else:
|
|
37
45
|
top_level_keys = {"token", "org"}
|
|
38
46
|
org_sections = {k: v for k, v in config_data.items() if k not in top_level_keys}
|
|
39
47
|
|
|
40
48
|
if not all(isinstance(e, dict) for e in org_sections.values()):
|
|
41
|
-
|
|
42
|
-
"Pipecat Cloud config file is not valid TOML. Organization sections must be dictionaries. Please log out and log back in."
|
|
43
|
-
)
|
|
44
|
-
else:
|
|
45
|
-
config_problem = ""
|
|
49
|
+
config_problem = "Pipecat Cloud config file is not valid TOML. Organization sections must be dictionaries. Please log out and log back in."
|
|
46
50
|
if config_problem:
|
|
47
51
|
raise ConfigError(config_problem)
|
|
48
52
|
|
|
@@ -87,8 +91,14 @@ def update_user_config(
|
|
|
87
91
|
|
|
88
92
|
try:
|
|
89
93
|
_write_user_config(existing_config)
|
|
90
|
-
except
|
|
91
|
-
raise ConfigError
|
|
94
|
+
except PermissionError:
|
|
95
|
+
raise ConfigError(f"Permission denied when writing to {user_config_path}")
|
|
96
|
+
except FileNotFoundError:
|
|
97
|
+
raise ConfigError(f"Cannot create configuration directory for {user_config_path}")
|
|
98
|
+
except IOError as e:
|
|
99
|
+
raise ConfigError(f"IO error when writing configuration: {str(e)}")
|
|
100
|
+
except Exception as e:
|
|
101
|
+
raise ConfigError(f"Unexpected error updating configuration: {str(e)}")
|
|
92
102
|
|
|
93
103
|
|
|
94
104
|
# --- Config
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
from typing import Optional, Union
|
|
8
8
|
|
|
9
|
+
from pipecatcloud.cli import PIPECAT_CLI_NAME
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
class Error(Exception):
|
|
11
13
|
"""Base class for exceptions in this module."""
|
|
@@ -24,7 +26,7 @@ class AuthError(Error):
|
|
|
24
26
|
|
|
25
27
|
def __init__(
|
|
26
28
|
self,
|
|
27
|
-
message: str = "Unauthorized / token expired. Please run `
|
|
29
|
+
message: str = f"Unauthorized / token expired. Please run `{PIPECAT_CLI_NAME} auth login` to login again.",
|
|
28
30
|
):
|
|
29
31
|
self.message = message
|
|
30
32
|
super().__init__(self.message)
|
|
@@ -37,6 +39,10 @@ class InvalidError(Error):
|
|
|
37
39
|
class ConfigError(Error):
|
|
38
40
|
"""Raised when config is unable to be stored or updated"""
|
|
39
41
|
|
|
42
|
+
def __init__(self, message: str = "Failed to update configuration"):
|
|
43
|
+
self.message = message
|
|
44
|
+
super().__init__(self.message)
|
|
45
|
+
|
|
40
46
|
|
|
41
47
|
class AgentNotHealthyError(Error):
|
|
42
48
|
"""Raised when agent is not healthy and cannot be started."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: pipecatcloud
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.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/
|
|
@@ -19,7 +19,7 @@ Requires-Dist: toml~=0.10.2
|
|
|
19
19
|
Requires-Dist: questionary~=2.1.0
|
|
20
20
|
|
|
21
21
|
<h1><div align="center">
|
|
22
|
-
<img alt="pipecat cloud" width="500px" height="auto" src="
|
|
22
|
+
<img alt="pipecat cloud" width="500px" height="auto" src="https://raw.githubusercontent.com/daily-co/pipecat-cloud/main/pipecat-cloud.png">
|
|
23
23
|
</div></h1>
|
|
24
24
|
|
|
25
25
|
[](https://docs.pipecat.daily.co)
|
|
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
|