pipecatcloud 0.1.4__tar.gz → 0.1.6__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.4 → pipecatcloud-0.1.6}/CHANGELOG.md +22 -0
- {pipecatcloud-0.1.4/src/pipecatcloud.egg-info → pipecatcloud-0.1.6}/PKG-INFO +1 -1
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/pyproject.toml +1 -1
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/deploy_utils.py +53 -12
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/api.py +27 -14
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/api.py +1 -1
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/agent.py +22 -9
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/deploy.py +60 -27
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6/src/pipecatcloud.egg-info}/PKG-INFO +1 -1
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/.github/workflows/publish-pypi.yml +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/.github/workflows/publish-test.yml +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/.github/workflows/python-publish.yml +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/.gitignore +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/LICENSE +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/README.md +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/dev-requirements.txt +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/pipecat-cloud.png +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/setup.cfg +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/__init__.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/__main__.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/__version__.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/__init__.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/async_utils.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/auth_utils.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/console_utils.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/local_runner.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/agent.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/__init__.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/__init__.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/auth.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/init.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/organizations.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/run.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/secrets.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/config.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/entry_point.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/config.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/exception.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud/session.py +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/SOURCES.txt +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/requires.txt +0 -0
- {pipecatcloud-0.1.4 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/top_level.txt +0 -0
|
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.6] - 2025-04-25
|
|
11
|
+
|
|
12
|
+
# Changed
|
|
13
|
+
|
|
14
|
+
- `min-instances` and `max-instances` has been changed to reflect API terminology changes.
|
|
15
|
+
|
|
16
|
+
## [0.1.5] - 2025-04-09
|
|
17
|
+
|
|
18
|
+
# Added
|
|
19
|
+
|
|
20
|
+
- `deploy` command now accepts a `--enable-krisp / -krisp` which enables Krisp integration for your pipeline.
|
|
21
|
+
|
|
22
|
+
# Changed
|
|
23
|
+
|
|
24
|
+
- `start` command now takes agent name from `pcc-deploy.toml` where applicable
|
|
25
|
+
- API error handling now checks `response.ok` and properly checks for error codes for all non-ok responses
|
|
26
|
+
|
|
27
|
+
# Fixed
|
|
28
|
+
|
|
29
|
+
- REST and cURL requests now render errors correctly
|
|
30
|
+
|
|
31
|
+
|
|
10
32
|
## [0.1.4] - 2025-03-28
|
|
11
33
|
|
|
12
34
|
### Changed
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
#
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
|
-
|
|
8
|
+
import functools
|
|
9
|
+
from typing import Optional, Callable, Any
|
|
9
10
|
|
|
10
11
|
import toml
|
|
11
|
-
from attr import dataclass
|
|
12
|
+
from attr import dataclass, field
|
|
12
13
|
from loguru import logger
|
|
13
14
|
|
|
14
15
|
from pipecatcloud.exception import ConfigFileError
|
|
@@ -22,23 +23,37 @@ DEPLOY_STATUS_MAP = {
|
|
|
22
23
|
|
|
23
24
|
@dataclass
|
|
24
25
|
class ScalingParams:
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
min_agents: Optional[int] = 0
|
|
27
|
+
max_agents: Optional[int] = None
|
|
28
|
+
# @deprecated
|
|
29
|
+
min_instances: Optional[int] = field(default=None, metadata={"deprecated": True})
|
|
30
|
+
# @deprecated
|
|
31
|
+
max_instances: Optional[int] = field(default=None, metadata={"deprecated": True})
|
|
27
32
|
|
|
28
33
|
def __attrs_post_init__(self):
|
|
34
|
+
# Handle deprecated fields
|
|
29
35
|
if self.min_instances is not None:
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
logger.warning("min_instances is deprecated, use min_agents instead")
|
|
37
|
+
self.min_agents = self.min_instances
|
|
32
38
|
|
|
33
39
|
if self.max_instances is not None:
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
logger.warning("max_instances is deprecated, use max_agents instead")
|
|
41
|
+
self.max_agents = self.max_instances
|
|
36
42
|
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
# Validation
|
|
44
|
+
if self.min_agents is not None:
|
|
45
|
+
if self.min_agents < 0:
|
|
46
|
+
raise ValueError("min_agents must be greater than or equal to 0")
|
|
47
|
+
|
|
48
|
+
if self.max_agents is not None:
|
|
49
|
+
if self.max_agents < 1:
|
|
50
|
+
raise ValueError("max_agents must be greater than 0")
|
|
51
|
+
|
|
52
|
+
if self.min_agents is not None and self.max_agents < self.min_agents:
|
|
53
|
+
raise ValueError("max_agents must be greater than or equal to min_agents")
|
|
39
54
|
|
|
40
55
|
def to_dict(self):
|
|
41
|
-
return {"
|
|
56
|
+
return {"min_agents": self.min_agents, "max_agents": self.max_agents}
|
|
42
57
|
|
|
43
58
|
|
|
44
59
|
@dataclass
|
|
@@ -48,6 +63,7 @@ class DeployConfigParams:
|
|
|
48
63
|
image_credentials: Optional[str] = None
|
|
49
64
|
secret_set: Optional[str] = None
|
|
50
65
|
scaling: ScalingParams = ScalingParams()
|
|
66
|
+
enable_krisp: bool = False
|
|
51
67
|
|
|
52
68
|
def __attrs_post_init__(self):
|
|
53
69
|
if self.image is not None and ":" not in self.image:
|
|
@@ -60,6 +76,7 @@ class DeployConfigParams:
|
|
|
60
76
|
"image_credentials": self.image_credentials,
|
|
61
77
|
"secret_set": self.secret_set,
|
|
62
78
|
"scaling": self.scaling.to_dict() if self.scaling else None,
|
|
79
|
+
"enable_krisp": self.enable_krisp,
|
|
63
80
|
}
|
|
64
81
|
|
|
65
82
|
|
|
@@ -87,7 +104,14 @@ def load_deploy_config_file() -> Optional[DeployConfigParams]:
|
|
|
87
104
|
)
|
|
88
105
|
|
|
89
106
|
# Check for unexpected keys
|
|
90
|
-
expected_keys = {
|
|
107
|
+
expected_keys = {
|
|
108
|
+
"agent_name",
|
|
109
|
+
"image",
|
|
110
|
+
"image_credentials",
|
|
111
|
+
"secret_set",
|
|
112
|
+
"scaling",
|
|
113
|
+
"enable_krisp",
|
|
114
|
+
}
|
|
91
115
|
unexpected_keys = set(config_data.keys()) - expected_keys
|
|
92
116
|
if unexpected_keys:
|
|
93
117
|
raise ConfigFileError(f"Unexpected keys in config file: {unexpected_keys}")
|
|
@@ -97,3 +121,20 @@ def load_deploy_config_file() -> Optional[DeployConfigParams]:
|
|
|
97
121
|
except Exception as e:
|
|
98
122
|
logger.debug(e)
|
|
99
123
|
raise ConfigFileError(str(e))
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def with_deploy_config(func: Callable) -> Callable:
|
|
127
|
+
"""
|
|
128
|
+
Decorator that loads the deploy config file and injects it into the function.
|
|
129
|
+
If the config file exists, it will be loaded and passed to the function as `deploy_config`.
|
|
130
|
+
"""
|
|
131
|
+
@functools.wraps(func)
|
|
132
|
+
def wrapper(*args, **kwargs):
|
|
133
|
+
try:
|
|
134
|
+
deploy_config = load_deploy_config_file()
|
|
135
|
+
kwargs['deploy_config'] = deploy_config
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.error(f"Error loading deploy config: {e}")
|
|
138
|
+
raise ConfigFileError(str(e))
|
|
139
|
+
return func(*args, **kwargs)
|
|
140
|
+
return wrapper
|
|
@@ -13,6 +13,7 @@ from loguru import logger
|
|
|
13
13
|
|
|
14
14
|
from pipecatcloud._utils.deploy_utils import DeployConfigParams
|
|
15
15
|
from pipecatcloud.config import config
|
|
16
|
+
from pipecatcloud.exception import AgentStartError
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
def api_method(func):
|
|
@@ -30,10 +31,11 @@ def api_method(func):
|
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
class _API:
|
|
33
|
-
def __init__(self, token: Optional[str] = None):
|
|
34
|
+
def __init__(self, token: Optional[str] = None, is_cli: bool = False):
|
|
34
35
|
self.token = token
|
|
35
36
|
self.error = None
|
|
36
37
|
self.bubble_next = False
|
|
38
|
+
self.is_cli = is_cli
|
|
37
39
|
|
|
38
40
|
@staticmethod
|
|
39
41
|
def construct_api_url(path: str) -> str:
|
|
@@ -60,6 +62,8 @@ class _API:
|
|
|
60
62
|
override_token: Optional[str] = None,
|
|
61
63
|
) -> Optional[dict]:
|
|
62
64
|
async with aiohttp.ClientSession() as session:
|
|
65
|
+
logger.debug(f"Request: {method} {url} {params} {json}")
|
|
66
|
+
|
|
63
67
|
response = await session.request(
|
|
64
68
|
method=method,
|
|
65
69
|
url=url,
|
|
@@ -67,21 +71,23 @@ class _API:
|
|
|
67
71
|
params=params,
|
|
68
72
|
json=json,
|
|
69
73
|
)
|
|
74
|
+
|
|
70
75
|
if not response.ok:
|
|
71
|
-
|
|
76
|
+
logger.debug(f"Response not ok: {response.status} {response.reason}")
|
|
77
|
+
if self.is_cli and not_found_is_empty and response.status == 404:
|
|
72
78
|
return None
|
|
73
79
|
|
|
74
80
|
# Extract PCC error code, where applicable
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
try:
|
|
82
|
+
# Try to parse the error as JSON
|
|
83
|
+
error_data = await response.json()
|
|
84
|
+
self.error = error_data
|
|
85
|
+
except Exception:
|
|
86
|
+
# Fallback structure matching API format
|
|
87
|
+
self.error = {
|
|
88
|
+
"error": response.reason or "Bad Request",
|
|
89
|
+
"code": str(
|
|
90
|
+
response.status)}
|
|
85
91
|
response.raise_for_status()
|
|
86
92
|
|
|
87
93
|
return await response.json()
|
|
@@ -100,6 +106,12 @@ class _API:
|
|
|
100
106
|
if live and not self.bubble_next:
|
|
101
107
|
live.stop()
|
|
102
108
|
|
|
109
|
+
if not self.is_cli and self.error and not self.bubble_next:
|
|
110
|
+
if isinstance(self.error, dict) and self.error.get("status", "429"):
|
|
111
|
+
raise AgentStartError(self.error)
|
|
112
|
+
else:
|
|
113
|
+
raise e
|
|
114
|
+
|
|
103
115
|
if self.error and not self.bubble_next:
|
|
104
116
|
logger.debug(e)
|
|
105
117
|
self.print_error()
|
|
@@ -305,9 +317,10 @@ class _API:
|
|
|
305
317
|
"imagePullSecretSet": deploy_config.image_credentials,
|
|
306
318
|
"secretSet": deploy_config.secret_set,
|
|
307
319
|
"autoScaling": {
|
|
308
|
-
"
|
|
309
|
-
"
|
|
320
|
+
"minAgents": deploy_config.scaling.min_agents,
|
|
321
|
+
"maxAgents": deploy_config.scaling.max_agents,
|
|
310
322
|
},
|
|
323
|
+
"enableKrisp": deploy_config.enable_krisp,
|
|
311
324
|
}
|
|
312
325
|
|
|
313
326
|
# Remove None values recursively
|
|
@@ -25,6 +25,7 @@ from pipecatcloud._utils.console_utils import console, format_timestamp
|
|
|
25
25
|
from pipecatcloud.cli import PIPECAT_CLI_NAME
|
|
26
26
|
from pipecatcloud.cli.api import API
|
|
27
27
|
from pipecatcloud.cli.config import config
|
|
28
|
+
from pipecatcloud._utils.deploy_utils import with_deploy_config, DeployConfigParams
|
|
28
29
|
|
|
29
30
|
agent_cli = typer.Typer(name="agent", help="Agent management", no_args_is_help=True)
|
|
30
31
|
|
|
@@ -53,8 +54,7 @@ async def list(
|
|
|
53
54
|
if not data or len(data) == 0:
|
|
54
55
|
console.error(
|
|
55
56
|
f"[red]No agents found for namespace / organization '{org}'[/red]\n\n"
|
|
56
|
-
f"[dim]Please deploy an agent first using[/dim] [bold cyan]{PIPECAT_CLI_NAME} deploy[/bold cyan]"
|
|
57
|
-
)
|
|
57
|
+
f"[dim]Please deploy an agent first using[/dim] [bold cyan]{PIPECAT_CLI_NAME} deploy[/bold cyan]")
|
|
58
58
|
return typer.Exit(1)
|
|
59
59
|
|
|
60
60
|
else:
|
|
@@ -137,11 +137,11 @@ async def status(
|
|
|
137
137
|
if autoscaling_data:
|
|
138
138
|
scaling_renderables = [
|
|
139
139
|
Panel(
|
|
140
|
-
f"[bold]Minimum
|
|
140
|
+
f"[bold]Minimum Agents[/bold]\n{autoscaling_data.get('minAgents', 0)}",
|
|
141
141
|
expand=True,
|
|
142
142
|
),
|
|
143
143
|
Panel(
|
|
144
|
-
f"[bold]Maximum
|
|
144
|
+
f"[bold]Maximum Agents[/bold]\n{autoscaling_data.get('maxAgents', 0)}",
|
|
145
145
|
expand=True,
|
|
146
146
|
),
|
|
147
147
|
]
|
|
@@ -443,8 +443,10 @@ async def deployments(
|
|
|
443
443
|
@agent_cli.command(name="start", help="Start an agent instance")
|
|
444
444
|
@synchronizer.create_blocking
|
|
445
445
|
@requires_login
|
|
446
|
+
@with_deploy_config
|
|
446
447
|
async def start(
|
|
447
|
-
|
|
448
|
+
deploy_config=typer.Option(None, hidden=True),
|
|
449
|
+
agent_name: str = typer.Argument(None, help="Name of the agent to start e.g. 'my-agent'"),
|
|
448
450
|
force: bool = typer.Option(
|
|
449
451
|
False,
|
|
450
452
|
"--force",
|
|
@@ -494,6 +496,19 @@ async def start(
|
|
|
494
496
|
"CLI provided" if api_key else config.get("default_public_key_name")
|
|
495
497
|
)
|
|
496
498
|
|
|
499
|
+
# Load values from deployment config file (if one exists)
|
|
500
|
+
partial_config = deploy_config or DeployConfigParams()
|
|
501
|
+
|
|
502
|
+
# Get agent name from pcc-deploy.toml if not provided
|
|
503
|
+
if not agent_name:
|
|
504
|
+
default_agent_name = partial_config.agent_name
|
|
505
|
+
|
|
506
|
+
if not default_agent_name:
|
|
507
|
+
console.error("No target agent name provided")
|
|
508
|
+
return typer.Exit(1)
|
|
509
|
+
|
|
510
|
+
agent_name = default_agent_name
|
|
511
|
+
|
|
497
512
|
if not default_public_api_key:
|
|
498
513
|
console.print(
|
|
499
514
|
Panel(
|
|
@@ -502,8 +517,7 @@ async def start(
|
|
|
502
517
|
title="Public API Key Required",
|
|
503
518
|
title_align="left",
|
|
504
519
|
border_style="yellow",
|
|
505
|
-
)
|
|
506
|
-
)
|
|
520
|
+
))
|
|
507
521
|
|
|
508
522
|
return typer.Exit(1)
|
|
509
523
|
|
|
@@ -533,8 +547,7 @@ async def start(
|
|
|
533
547
|
title=f"[bold]Start Request for agent: {agent_name}[/bold]",
|
|
534
548
|
title_align="left",
|
|
535
549
|
border_style="yellow",
|
|
536
|
-
)
|
|
537
|
-
)
|
|
550
|
+
))
|
|
538
551
|
if not await questionary.confirm(
|
|
539
552
|
"Are you sure you want to start an active session for this agent?"
|
|
540
553
|
).ask_async():
|
|
@@ -20,7 +20,7 @@ from pipecatcloud._utils.console_utils import console
|
|
|
20
20
|
from pipecatcloud._utils.deploy_utils import (
|
|
21
21
|
DeployConfigParams,
|
|
22
22
|
ScalingParams,
|
|
23
|
-
|
|
23
|
+
with_deploy_config,
|
|
24
24
|
)
|
|
25
25
|
from pipecatcloud.cli import PIPECAT_CLI_NAME
|
|
26
26
|
from pipecatcloud.cli.api import API
|
|
@@ -223,26 +223,28 @@ def create_deploy_command(app: typer.Typer):
|
|
|
223
223
|
@app.command(name="deploy", help="Deploy agent to Pipecat Cloud")
|
|
224
224
|
@synchronizer.create_blocking
|
|
225
225
|
@requires_login
|
|
226
|
+
@with_deploy_config
|
|
226
227
|
async def deploy(
|
|
228
|
+
deploy_config=typer.Option(None, hidden=True),
|
|
227
229
|
agent_name: str = typer.Argument(
|
|
228
230
|
None, help="Name of the agent to deploy e.g. 'my-agent'", show_default=False
|
|
229
231
|
),
|
|
230
232
|
image: str = typer.Argument(
|
|
231
233
|
None, help="Docker image location e.g. 'my-image:latest'", show_default=False
|
|
232
234
|
),
|
|
233
|
-
|
|
235
|
+
min_agents: int = typer.Option(
|
|
234
236
|
None,
|
|
235
|
-
"--min-
|
|
237
|
+
"--min-agents",
|
|
236
238
|
"-min",
|
|
237
|
-
help="Minimum number of
|
|
239
|
+
help="Minimum number of agents to keep warm",
|
|
238
240
|
rich_help_panel="Deployment Configuration",
|
|
239
241
|
min=0,
|
|
240
242
|
),
|
|
241
|
-
|
|
243
|
+
max_agents: int = typer.Option(
|
|
242
244
|
None,
|
|
243
|
-
"--max-
|
|
245
|
+
"--max-agents",
|
|
244
246
|
"-max",
|
|
245
|
-
help="Maximum number of allowed
|
|
247
|
+
help="Maximum number of allowed agents",
|
|
246
248
|
rich_help_panel="Deployment Configuration",
|
|
247
249
|
min=1,
|
|
248
250
|
max=50,
|
|
@@ -268,13 +270,47 @@ def create_deploy_command(app: typer.Typer):
|
|
|
268
270
|
help="Image pull secret to use for deployment",
|
|
269
271
|
rich_help_panel="Deployment Configuration",
|
|
270
272
|
),
|
|
273
|
+
krisp: bool = typer.Option(
|
|
274
|
+
False,
|
|
275
|
+
"--enable-krisp",
|
|
276
|
+
"-krisp",
|
|
277
|
+
help="Enable Krisp integration for this deployment",
|
|
278
|
+
rich_help_panel="Deployment Configuration",
|
|
279
|
+
),
|
|
271
280
|
skip_confirm: bool = typer.Option(
|
|
272
281
|
False,
|
|
273
282
|
"--force",
|
|
274
283
|
"-f",
|
|
275
284
|
help="Force deployment / skip confirmation",
|
|
276
285
|
),
|
|
286
|
+
# @deprecated
|
|
287
|
+
min_instances: int = typer.Option(
|
|
288
|
+
None,
|
|
289
|
+
"--min-instances",
|
|
290
|
+
help="[Deprecated] Use --min-agents instead",
|
|
291
|
+
hidden=True,
|
|
292
|
+
min=0,
|
|
293
|
+
),
|
|
294
|
+
# @deprecated
|
|
295
|
+
max_instances: int = typer.Option(
|
|
296
|
+
None,
|
|
297
|
+
"--max-instances",
|
|
298
|
+
help="[Deprecated] Use --max-agents instead",
|
|
299
|
+
hidden=True,
|
|
300
|
+
min=1,
|
|
301
|
+
max=50,
|
|
302
|
+
),
|
|
277
303
|
):
|
|
304
|
+
|
|
305
|
+
# Handle @deprecated options
|
|
306
|
+
if min_instances is not None:
|
|
307
|
+
logger.warning("min_instances is deprecated, use min_agents instead")
|
|
308
|
+
min_agents = min_instances
|
|
309
|
+
|
|
310
|
+
if max_instances is not None:
|
|
311
|
+
logger.warning("max_instances is deprecated, use max_agents instead")
|
|
312
|
+
max_agents = max_instances
|
|
313
|
+
|
|
278
314
|
org = organization or config.get("org")
|
|
279
315
|
|
|
280
316
|
# Compose deployment config from CLI options and config file (if provided)
|
|
@@ -283,15 +319,7 @@ def create_deploy_command(app: typer.Typer):
|
|
|
283
319
|
# 2. Values from the config toml file
|
|
284
320
|
# 3. CLI command defaults
|
|
285
321
|
|
|
286
|
-
partial_config = DeployConfigParams()
|
|
287
|
-
|
|
288
|
-
# Load values from deployment config file (if one exists)
|
|
289
|
-
try:
|
|
290
|
-
if deploy_config := load_deploy_config_file():
|
|
291
|
-
partial_config = deploy_config
|
|
292
|
-
except Exception as e:
|
|
293
|
-
console.error(str(e))
|
|
294
|
-
return typer.Exit()
|
|
322
|
+
partial_config = deploy_config or DeployConfigParams()
|
|
295
323
|
|
|
296
324
|
# Override any local config values from passed CLI arguments
|
|
297
325
|
partial_config.agent_name = agent_name or partial_config.agent_name
|
|
@@ -299,13 +327,14 @@ def create_deploy_command(app: typer.Typer):
|
|
|
299
327
|
partial_config.image_credentials = credentials or partial_config.image_credentials
|
|
300
328
|
partial_config.secret_set = secret_set or partial_config.secret_set
|
|
301
329
|
partial_config.scaling = ScalingParams(
|
|
302
|
-
|
|
303
|
-
if
|
|
304
|
-
else partial_config.scaling.
|
|
305
|
-
|
|
306
|
-
if
|
|
307
|
-
else partial_config.scaling.
|
|
330
|
+
min_agents=min_agents
|
|
331
|
+
if min_agents is not None
|
|
332
|
+
else partial_config.scaling.min_agents,
|
|
333
|
+
max_agents=max_agents
|
|
334
|
+
if max_agents is not None
|
|
335
|
+
else partial_config.scaling.max_agents,
|
|
308
336
|
)
|
|
337
|
+
partial_config.enable_krisp = krisp or partial_config.enable_krisp
|
|
309
338
|
|
|
310
339
|
# Assert agent name and image are provided
|
|
311
340
|
if not partial_config.agent_name:
|
|
@@ -320,8 +349,11 @@ def create_deploy_command(app: typer.Typer):
|
|
|
320
349
|
table = Table(show_header=False, border_style="dim", show_edge=True, show_lines=True)
|
|
321
350
|
table.add_column("Property", style="cyan")
|
|
322
351
|
table.add_column("Value", style="green")
|
|
323
|
-
table.add_row("Min
|
|
324
|
-
|
|
352
|
+
table.add_row("Min agents", str(partial_config.scaling.min_agents))
|
|
353
|
+
if partial_config.scaling.max_agents:
|
|
354
|
+
table.add_row("Max agents", str(partial_config.scaling.max_agents))
|
|
355
|
+
else:
|
|
356
|
+
table.add_row("Max agents", "[dim]Use existing or default[/dim]")
|
|
325
357
|
|
|
326
358
|
content = Group(
|
|
327
359
|
(f"[bold white]Agent name:[/bold white] [green]{partial_config.agent_name}[/green]"),
|
|
@@ -329,17 +361,18 @@ def create_deploy_command(app: typer.Typer):
|
|
|
329
361
|
(f"[bold white]Organization:[/bold white] [green]{org}[/green]"),
|
|
330
362
|
(f"[bold white]Secret set:[/bold white] {'[dim]None[/dim]' if not partial_config.secret_set else '[green] '+ partial_config.secret_set + '[/green]'}"),
|
|
331
363
|
(f"[bold white]Image pull secret:[/bold white] {'[dim]None[/dim]' if not partial_config.image_credentials else '[green]' + partial_config.image_credentials + '[/green]'}"),
|
|
364
|
+
(f"[bold white]Krisp:[/bold white] {'[dim]Disabled[/dim]' if not partial_config.enable_krisp else '[green]Enabled[/green]'}"),
|
|
332
365
|
"\n[dim]Scaling configuration:[/dim]",
|
|
333
366
|
table,
|
|
334
367
|
*
|
|
335
368
|
(
|
|
336
369
|
[
|
|
337
370
|
Text(
|
|
338
|
-
f"Note: Usage costs will apply for {partial_config.scaling.
|
|
371
|
+
f"Note: Usage costs will apply for {partial_config.scaling.min_agents} reserved agent(s). Please see: https://www.daily.co/pricing/pipecat-cloud/",
|
|
339
372
|
style="red",
|
|
340
|
-
)] if partial_config.scaling.
|
|
373
|
+
)] if partial_config.scaling.min_agents else [
|
|
341
374
|
Text(
|
|
342
|
-
"Note: Deploying with 0 minimum
|
|
375
|
+
"Note: Deploying with 0 minimum agents may result in cold starts",
|
|
343
376
|
style="red",
|
|
344
377
|
)]),
|
|
345
378
|
)
|
|
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
|