agenta 0.36.3__py3-none-any.whl → 0.36.4__py3-none-any.whl
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.
Potentially problematic release.
This version of agenta might be problematic. Click here for more details.
- agenta/__init__.py +5 -5
- agenta/client/Readme.md +3 -3
- agenta/client/__init__.py +294 -0
- agenta/client/client.py +3192 -466
- agenta/sdk/__init__.py +5 -5
- agenta/sdk/agenta_init.py +28 -54
- agenta/sdk/client.py +1 -1
- agenta/sdk/managers/shared.py +3 -3
- agenta/sdk/middleware/auth.py +18 -9
- agenta/sdk/middleware/config.py +0 -2
- agenta/sdk/middleware/vault.py +3 -3
- agenta/sdk/types.py +2 -2
- {agenta-0.36.3.dist-info → agenta-0.36.4.dist-info}/METADATA +1 -2
- agenta-0.36.4.dist-info/RECORD +236 -0
- agenta/cli/helper.py +0 -202
- agenta/cli/main.py +0 -229
- agenta/cli/telemetry.py +0 -50
- agenta/cli/variant_commands.py +0 -526
- agenta/cli/variant_configs.py +0 -49
- agenta/client/api.py +0 -74
- agenta/client/api_models.py +0 -34
- agenta/client/backend/__init__.py +0 -294
- agenta/client/backend/client.py +0 -3289
- agenta/client/exceptions.py +0 -2
- agenta/docker/docker-assets/Dockerfile.cloud.template +0 -9
- agenta/docker/docker-assets/Dockerfile.oss.template +0 -13
- agenta/docker/docker-assets/Dockerfile.template +0 -13
- agenta/docker/docker-assets/README.md +0 -1
- agenta/docker/docker-assets/entrypoint.sh +0 -7
- agenta/docker/docker-assets/lambda_function.py +0 -6
- agenta/docker/docker-assets/main.py +0 -13
- agenta/docker/docker_utils.py +0 -100
- agenta-0.36.3.dist-info/RECORD +0 -255
- agenta-0.36.3.dist-info/entry_points.txt +0 -3
- /agenta/client/{backend/access_control → access_control}/__init__.py +0 -0
- /agenta/client/{backend/access_control → access_control}/client.py +0 -0
- /agenta/client/{backend/admin → admin}/__init__.py +0 -0
- /agenta/client/{backend/admin → admin}/client.py +0 -0
- /agenta/client/{backend/apps → apps}/__init__.py +0 -0
- /agenta/client/{backend/apps → apps}/client.py +0 -0
- /agenta/client/{backend/bases → bases}/__init__.py +0 -0
- /agenta/client/{backend/bases → bases}/client.py +0 -0
- /agenta/client/{backend/configs → configs}/__init__.py +0 -0
- /agenta/client/{backend/configs → configs}/client.py +0 -0
- /agenta/client/{backend/containers → containers}/__init__.py +0 -0
- /agenta/client/{backend/containers → containers}/client.py +0 -0
- /agenta/client/{backend/containers → containers}/types/__init__.py +0 -0
- /agenta/client/{backend/containers → containers}/types/container_templates_response.py +0 -0
- /agenta/client/{backend/core → core}/__init__.py +0 -0
- /agenta/client/{backend/core → core}/api_error.py +0 -0
- /agenta/client/{backend/core → core}/client_wrapper.py +0 -0
- /agenta/client/{backend/core → core}/datetime_utils.py +0 -0
- /agenta/client/{backend/core → core}/file.py +0 -0
- /agenta/client/{backend/core → core}/http_client.py +0 -0
- /agenta/client/{backend/core → core}/jsonable_encoder.py +0 -0
- /agenta/client/{backend/core → core}/pydantic_utilities.py +0 -0
- /agenta/client/{backend/core → core}/query_encoder.py +0 -0
- /agenta/client/{backend/core → core}/remove_none_from_dict.py +0 -0
- /agenta/client/{backend/core → core}/request_options.py +0 -0
- /agenta/client/{backend/core → core}/serialization.py +0 -0
- /agenta/client/{backend/environments → environments}/__init__.py +0 -0
- /agenta/client/{backend/environments → environments}/client.py +0 -0
- /agenta/client/{backend/errors → errors}/__init__.py +0 -0
- /agenta/client/{backend/errors → errors}/unprocessable_entity_error.py +0 -0
- /agenta/client/{backend/evaluations → evaluations}/__init__.py +0 -0
- /agenta/client/{backend/evaluations → evaluations}/client.py +0 -0
- /agenta/client/{backend/evaluators → evaluators}/__init__.py +0 -0
- /agenta/client/{backend/evaluators → evaluators}/client.py +0 -0
- /agenta/client/{backend/human_evaluations → human_evaluations}/__init__.py +0 -0
- /agenta/client/{backend/human_evaluations → human_evaluations}/client.py +0 -0
- /agenta/client/{backend/observability → observability}/__init__.py +0 -0
- /agenta/client/{backend/observability → observability}/client.py +0 -0
- /agenta/client/{backend/observability → observability}/types/__init__.py +0 -0
- /agenta/client/{backend/observability → observability}/types/format.py +0 -0
- /agenta/client/{backend/observability → observability}/types/query_analytics_response.py +0 -0
- /agenta/client/{backend/observability → observability}/types/query_traces_response.py +0 -0
- /agenta/client/{backend/scopes → scopes}/__init__.py +0 -0
- /agenta/client/{backend/scopes → scopes}/client.py +0 -0
- /agenta/client/{backend/testsets → testsets}/__init__.py +0 -0
- /agenta/client/{backend/testsets → testsets}/client.py +0 -0
- /agenta/client/{backend/types → types}/__init__.py +0 -0
- /agenta/client/{backend/types → types}/account_response.py +0 -0
- /agenta/client/{backend/types → types}/agenta_node_dto.py +0 -0
- /agenta/client/{backend/types → types}/agenta_node_dto_nodes_value.py +0 -0
- /agenta/client/{backend/types → types}/agenta_nodes_response.py +0 -0
- /agenta/client/{backend/types → types}/agenta_root_dto.py +0 -0
- /agenta/client/{backend/types → types}/agenta_roots_response.py +0 -0
- /agenta/client/{backend/types → types}/agenta_tree_dto.py +0 -0
- /agenta/client/{backend/types → types}/agenta_trees_response.py +0 -0
- /agenta/client/{backend/types → types}/aggregated_result.py +0 -0
- /agenta/client/{backend/types → types}/aggregated_result_evaluator_config.py +0 -0
- /agenta/client/{backend/types → types}/analytics_response.py +0 -0
- /agenta/client/{backend/types → types}/app.py +0 -0
- /agenta/client/{backend/types → types}/app_variant_response.py +0 -0
- /agenta/client/{backend/types → types}/app_variant_revision.py +0 -0
- /agenta/client/{backend/types → types}/base_output.py +0 -0
- /agenta/client/{backend/types → types}/body_import_testset.py +0 -0
- /agenta/client/{backend/types → types}/bucket_dto.py +0 -0
- /agenta/client/{backend/types → types}/collect_status_response.py +0 -0
- /agenta/client/{backend/types → types}/config_db.py +0 -0
- /agenta/client/{backend/types → types}/config_dto.py +0 -0
- /agenta/client/{backend/types → types}/config_response_model.py +0 -0
- /agenta/client/{backend/types → types}/correct_answer.py +0 -0
- /agenta/client/{backend/types → types}/create_app_output.py +0 -0
- /agenta/client/{backend/types → types}/delete_evaluation.py +0 -0
- /agenta/client/{backend/types → types}/docker_env_vars.py +0 -0
- /agenta/client/{backend/types → types}/environment_output.py +0 -0
- /agenta/client/{backend/types → types}/environment_output_extended.py +0 -0
- /agenta/client/{backend/types → types}/environment_revision.py +0 -0
- /agenta/client/{backend/types → types}/error.py +0 -0
- /agenta/client/{backend/types → types}/evaluation.py +0 -0
- /agenta/client/{backend/types → types}/evaluation_scenario.py +0 -0
- /agenta/client/{backend/types → types}/evaluation_scenario_input.py +0 -0
- /agenta/client/{backend/types → types}/evaluation_scenario_output.py +0 -0
- /agenta/client/{backend/types → types}/evaluation_scenario_result.py +0 -0
- /agenta/client/{backend/types → types}/evaluation_status_enum.py +0 -0
- /agenta/client/{backend/types → types}/evaluation_type.py +0 -0
- /agenta/client/{backend/types → types}/evaluator.py +0 -0
- /agenta/client/{backend/types → types}/evaluator_config.py +0 -0
- /agenta/client/{backend/types → types}/evaluator_mapping_output_interface.py +0 -0
- /agenta/client/{backend/types → types}/evaluator_output_interface.py +0 -0
- /agenta/client/{backend/types → types}/exception_dto.py +0 -0
- /agenta/client/{backend/types → types}/get_config_response.py +0 -0
- /agenta/client/{backend/types → types}/header_dto.py +0 -0
- /agenta/client/{backend/types → types}/http_validation_error.py +0 -0
- /agenta/client/{backend/types → types}/human_evaluation.py +0 -0
- /agenta/client/{backend/types → types}/human_evaluation_scenario.py +0 -0
- /agenta/client/{backend/types → types}/human_evaluation_scenario_input.py +0 -0
- /agenta/client/{backend/types → types}/human_evaluation_scenario_output.py +0 -0
- /agenta/client/{backend/types → types}/image.py +0 -0
- /agenta/client/{backend/types → types}/invite_request.py +0 -0
- /agenta/client/{backend/types → types}/legacy_analytics_response.py +0 -0
- /agenta/client/{backend/types → types}/legacy_data_point.py +0 -0
- /agenta/client/{backend/types → types}/legacy_scope_request.py +0 -0
- /agenta/client/{backend/types → types}/legacy_scopes_response.py +0 -0
- /agenta/client/{backend/types → types}/legacy_user_request.py +0 -0
- /agenta/client/{backend/types → types}/legacy_user_response.py +0 -0
- /agenta/client/{backend/types → types}/lifecycle_dto.py +0 -0
- /agenta/client/{backend/types → types}/link_dto.py +0 -0
- /agenta/client/{backend/types → types}/list_api_keys_response.py +0 -0
- /agenta/client/{backend/types → types}/llm_run_rate_limit.py +0 -0
- /agenta/client/{backend/types → types}/metrics_dto.py +0 -0
- /agenta/client/{backend/types → types}/new_testset.py +0 -0
- /agenta/client/{backend/types → types}/node_dto.py +0 -0
- /agenta/client/{backend/types → types}/node_type.py +0 -0
- /agenta/client/{backend/types → types}/o_tel_context_dto.py +0 -0
- /agenta/client/{backend/types → types}/o_tel_event_dto.py +0 -0
- /agenta/client/{backend/types → types}/o_tel_extra_dto.py +0 -0
- /agenta/client/{backend/types → types}/o_tel_link_dto.py +0 -0
- /agenta/client/{backend/types → types}/o_tel_span_dto.py +0 -0
- /agenta/client/{backend/types → types}/o_tel_span_kind.py +0 -0
- /agenta/client/{backend/types → types}/o_tel_spans_response.py +0 -0
- /agenta/client/{backend/types → types}/o_tel_status_code.py +0 -0
- /agenta/client/{backend/types → types}/organization.py +0 -0
- /agenta/client/{backend/types → types}/organization_membership_request.py +0 -0
- /agenta/client/{backend/types → types}/organization_output.py +0 -0
- /agenta/client/{backend/types → types}/organization_request.py +0 -0
- /agenta/client/{backend/types → types}/parent_dto.py +0 -0
- /agenta/client/{backend/types → types}/permission.py +0 -0
- /agenta/client/{backend/types → types}/project_membership_request.py +0 -0
- /agenta/client/{backend/types → types}/project_request.py +0 -0
- /agenta/client/{backend/types → types}/project_scope.py +0 -0
- /agenta/client/{backend/types → types}/projects_response.py +0 -0
- /agenta/client/{backend/types → types}/provider_key_dto.py +0 -0
- /agenta/client/{backend/types → types}/provider_kind.py +0 -0
- /agenta/client/{backend/types → types}/reference.py +0 -0
- /agenta/client/{backend/types → types}/reference_dto.py +0 -0
- /agenta/client/{backend/types → types}/reference_request_model.py +0 -0
- /agenta/client/{backend/types → types}/result.py +0 -0
- /agenta/client/{backend/types → types}/role.py +0 -0
- /agenta/client/{backend/types → types}/root_dto.py +0 -0
- /agenta/client/{backend/types → types}/scopes_response_model.py +0 -0
- /agenta/client/{backend/types → types}/score.py +0 -0
- /agenta/client/{backend/types → types}/secret_dto.py +0 -0
- /agenta/client/{backend/types → types}/secret_kind.py +0 -0
- /agenta/client/{backend/types → types}/secret_response_dto.py +0 -0
- /agenta/client/{backend/types → types}/simple_evaluation_output.py +0 -0
- /agenta/client/{backend/types → types}/span_dto.py +0 -0
- /agenta/client/{backend/types → types}/span_dto_nodes_value.py +0 -0
- /agenta/client/{backend/types → types}/status_code.py +0 -0
- /agenta/client/{backend/types → types}/status_dto.py +0 -0
- /agenta/client/{backend/types → types}/template.py +0 -0
- /agenta/client/{backend/types → types}/template_image_info.py +0 -0
- /agenta/client/{backend/types → types}/test_set_output_response.py +0 -0
- /agenta/client/{backend/types → types}/test_set_simple_response.py +0 -0
- /agenta/client/{backend/types → types}/time_dto.py +0 -0
- /agenta/client/{backend/types → types}/tree_dto.py +0 -0
- /agenta/client/{backend/types → types}/tree_type.py +0 -0
- /agenta/client/{backend/types → types}/update_app_output.py +0 -0
- /agenta/client/{backend/types → types}/uri.py +0 -0
- /agenta/client/{backend/types → types}/user_request.py +0 -0
- /agenta/client/{backend/types → types}/validation_error.py +0 -0
- /agenta/client/{backend/types → types}/validation_error_loc_item.py +0 -0
- /agenta/client/{backend/types → types}/variant_action.py +0 -0
- /agenta/client/{backend/types → types}/variant_action_enum.py +0 -0
- /agenta/client/{backend/types → types}/workspace_member_response.py +0 -0
- /agenta/client/{backend/types → types}/workspace_membership_request.py +0 -0
- /agenta/client/{backend/types → types}/workspace_permission.py +0 -0
- /agenta/client/{backend/types → types}/workspace_request.py +0 -0
- /agenta/client/{backend/types → types}/workspace_response.py +0 -0
- /agenta/client/{backend/types → types}/workspace_role.py +0 -0
- /agenta/client/{backend/types → types}/workspace_role_response.py +0 -0
- /agenta/client/{backend/variants → variants}/__init__.py +0 -0
- /agenta/client/{backend/variants → variants}/client.py +0 -0
- /agenta/client/{backend/variants → variants}/types/__init__.py +0 -0
- /agenta/client/{backend/variants → variants}/types/add_variant_from_base_and_config_response.py +0 -0
- /agenta/client/{backend/vault → vault}/__init__.py +0 -0
- /agenta/client/{backend/vault → vault}/client.py +0 -0
- {agenta-0.36.3.dist-info → agenta-0.36.4.dist-info}/WHEEL +0 -0
agenta/cli/variant_commands.py
DELETED
|
@@ -1,526 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import re
|
|
3
|
-
import sys
|
|
4
|
-
from typing import List
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
|
|
7
|
-
from requests.exceptions import ConnectionError
|
|
8
|
-
|
|
9
|
-
import click
|
|
10
|
-
import questionary
|
|
11
|
-
import toml
|
|
12
|
-
|
|
13
|
-
from agenta.cli import helper
|
|
14
|
-
from agenta.cli.telemetry import event_track
|
|
15
|
-
from agenta.client.backend.client import AgentaApi
|
|
16
|
-
from agenta.client.api import add_variant_to_server
|
|
17
|
-
from agenta.client.api_models import AppVariant, Image
|
|
18
|
-
from agenta.docker.docker_utils import build_tar_docker_container
|
|
19
|
-
from agenta.client.backend.types.variant_action import VariantAction
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
BACKEND_URL_SUFFIX = os.environ.get("BACKEND_URL_SUFFIX", "api")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@click.group()
|
|
26
|
-
def variant():
|
|
27
|
-
"""Commands for variants"""
|
|
28
|
-
pass
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def add_variant(
|
|
32
|
-
app_folder: str, file_name: str, host: str, overwrite: bool, config_name="default"
|
|
33
|
-
) -> str:
|
|
34
|
-
"""
|
|
35
|
-
Adds a variant to the backend. Sends the code as a tar to the backend, which then containerizes it and adds it to the backend store.
|
|
36
|
-
The app variant name to be added is
|
|
37
|
-
{file_name.removesuffix(".py")}.{config_name}
|
|
38
|
-
Args:
|
|
39
|
-
variant_name: the name of the variant
|
|
40
|
-
app_folder: the folder of the app
|
|
41
|
-
file_name: the name of the file to run.
|
|
42
|
-
config_name: the name of the config to use for now it is always default
|
|
43
|
-
Returns:
|
|
44
|
-
the name of the code base and variant(useful for serve)
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
app_path = Path(app_folder)
|
|
48
|
-
config_file = app_path / "config.toml"
|
|
49
|
-
config = toml.load(config_file)
|
|
50
|
-
|
|
51
|
-
app_name = config["app_name"]
|
|
52
|
-
app_id = config["app_id"]
|
|
53
|
-
api_key = config.get("api_key", "")
|
|
54
|
-
|
|
55
|
-
config_name = "default"
|
|
56
|
-
base_name = file_name.removesuffix(".py")
|
|
57
|
-
variant_name = f"{base_name}.{config_name}"
|
|
58
|
-
|
|
59
|
-
# check files in folder
|
|
60
|
-
app_file = app_path / file_name
|
|
61
|
-
if not app_file.exists():
|
|
62
|
-
click.echo(
|
|
63
|
-
click.style(
|
|
64
|
-
f"No {file_name} exists! Please make sure you are in the right directory",
|
|
65
|
-
fg="red",
|
|
66
|
-
)
|
|
67
|
-
)
|
|
68
|
-
return None
|
|
69
|
-
|
|
70
|
-
env_file = app_path / ".env"
|
|
71
|
-
if not env_file.exists():
|
|
72
|
-
continue_without_env = questionary.confirm(
|
|
73
|
-
"No .env file found! Are you sure you handled the API keys needed in your application?\n Do you want to continue without it?"
|
|
74
|
-
).ask()
|
|
75
|
-
if not continue_without_env:
|
|
76
|
-
click.echo("Operation cancelled.")
|
|
77
|
-
sys.exit(0)
|
|
78
|
-
|
|
79
|
-
requirements_file = app_path / "requirements.txt"
|
|
80
|
-
if not requirements_file.exists():
|
|
81
|
-
continue_without_requirements = questionary.confirm(
|
|
82
|
-
"No requirements.txt file found! Are you sure you do not need it in your application?\n Do you want to continue without it?"
|
|
83
|
-
).ask()
|
|
84
|
-
if not continue_without_requirements:
|
|
85
|
-
click.echo("Operation cancelled.")
|
|
86
|
-
sys.exit(0)
|
|
87
|
-
|
|
88
|
-
# Validate variant name
|
|
89
|
-
if not re.match("^[a-zA-Z0-9_]+$", base_name):
|
|
90
|
-
click.echo(
|
|
91
|
-
click.style(
|
|
92
|
-
"Invalid input. Please use only alphanumeric characters without spaces in the filename.",
|
|
93
|
-
fg="red",
|
|
94
|
-
)
|
|
95
|
-
)
|
|
96
|
-
sys.exit(0)
|
|
97
|
-
|
|
98
|
-
# update the config file with the variant names from the backend
|
|
99
|
-
variant_name = f"{base_name}.{config_name}"
|
|
100
|
-
|
|
101
|
-
client = AgentaApi(
|
|
102
|
-
base_url=f"{host}/{BACKEND_URL_SUFFIX}",
|
|
103
|
-
api_key=api_key,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
if variant_name in config["variants"] and not overwrite:
|
|
107
|
-
if not overwrite:
|
|
108
|
-
overwrite = questionary.confirm(
|
|
109
|
-
"This variant already exists. Do you want to overwrite it?"
|
|
110
|
-
).ask()
|
|
111
|
-
if not overwrite:
|
|
112
|
-
click.echo("Operation cancelled.")
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
try:
|
|
116
|
-
click.echo(
|
|
117
|
-
click.style(
|
|
118
|
-
f"Preparing code base {base_name} into a tar file...",
|
|
119
|
-
fg="bright_black",
|
|
120
|
-
)
|
|
121
|
-
)
|
|
122
|
-
tar_path = build_tar_docker_container(folder=app_path, file_name=file_name)
|
|
123
|
-
|
|
124
|
-
click.echo(
|
|
125
|
-
click.style(
|
|
126
|
-
f"Building code base {base_name} for {variant_name} into a docker image...",
|
|
127
|
-
fg="bright_black",
|
|
128
|
-
)
|
|
129
|
-
)
|
|
130
|
-
with tar_path.open("rb") as tar_file:
|
|
131
|
-
built_image: Image = client.containers.build_image(
|
|
132
|
-
app_id=app_id,
|
|
133
|
-
base_name=base_name,
|
|
134
|
-
tar_file=tar_file,
|
|
135
|
-
)
|
|
136
|
-
image = Image(**built_image.dict())
|
|
137
|
-
if tar_path.exists():
|
|
138
|
-
tar_path.unlink()
|
|
139
|
-
|
|
140
|
-
except Exception as ex:
|
|
141
|
-
click.echo(click.style(f"Error while building image: {ex}", fg="red"))
|
|
142
|
-
raise
|
|
143
|
-
try:
|
|
144
|
-
if overwrite:
|
|
145
|
-
click.echo(
|
|
146
|
-
click.style(
|
|
147
|
-
f"Updating {base_name} to server...",
|
|
148
|
-
fg="bright_black",
|
|
149
|
-
)
|
|
150
|
-
)
|
|
151
|
-
variant_id = config["variant_ids"][config["variants"].index(variant_name)]
|
|
152
|
-
client.variants.update_variant_image(
|
|
153
|
-
variant_id=variant_id,
|
|
154
|
-
docker_id=image.docker_id,
|
|
155
|
-
tags=image.tags,
|
|
156
|
-
type=image.type,
|
|
157
|
-
) # this automatically restarts
|
|
158
|
-
else:
|
|
159
|
-
click.echo(click.style(f"Adding {variant_name} to server...", fg="yellow"))
|
|
160
|
-
response = add_variant_to_server(
|
|
161
|
-
app_id,
|
|
162
|
-
base_name,
|
|
163
|
-
image,
|
|
164
|
-
f"{host}/{BACKEND_URL_SUFFIX}",
|
|
165
|
-
api_key,
|
|
166
|
-
)
|
|
167
|
-
variant_id = response["variant_id"]
|
|
168
|
-
config["variants"].append(variant_name)
|
|
169
|
-
config["variant_ids"].append(variant_id)
|
|
170
|
-
except Exception as ex:
|
|
171
|
-
if overwrite:
|
|
172
|
-
click.echo(click.style(f"Error while updating variant: {ex}", fg="red"))
|
|
173
|
-
else:
|
|
174
|
-
click.echo(click.style(f"Error while adding variant: {ex}", fg="red"))
|
|
175
|
-
raise
|
|
176
|
-
|
|
177
|
-
agenta_dir = Path.home() / ".agenta"
|
|
178
|
-
global_toml_file = toml.load(agenta_dir / "config.toml")
|
|
179
|
-
tracking_enabled: bool = global_toml_file["telemetry_tracking_enabled"]
|
|
180
|
-
if overwrite:
|
|
181
|
-
# Track a deployment event
|
|
182
|
-
if tracking_enabled:
|
|
183
|
-
get_user_id = client.fetch_user_profile()
|
|
184
|
-
user_id = get_user_id["id"]
|
|
185
|
-
event_track.capture_event(
|
|
186
|
-
"app_deployment",
|
|
187
|
-
body={
|
|
188
|
-
"app_id": app_id,
|
|
189
|
-
"deployed_by": user_id,
|
|
190
|
-
"environment": "CLI",
|
|
191
|
-
"version": "cloud" if api_key else "oss",
|
|
192
|
-
},
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
click.echo(
|
|
196
|
-
click.style(
|
|
197
|
-
f"Variant {variant_name} for App {app_name} updated successfully 🎉",
|
|
198
|
-
bold=True,
|
|
199
|
-
fg="green",
|
|
200
|
-
)
|
|
201
|
-
)
|
|
202
|
-
else:
|
|
203
|
-
# Track a deployment event
|
|
204
|
-
if tracking_enabled:
|
|
205
|
-
get_user_id = client.fetch_user_profile()
|
|
206
|
-
user_id = get_user_id["id"]
|
|
207
|
-
event_track.capture_event(
|
|
208
|
-
"app_deployment",
|
|
209
|
-
body={
|
|
210
|
-
"app_id": app_id,
|
|
211
|
-
"deployed_by": user_id,
|
|
212
|
-
"environment": "CLI",
|
|
213
|
-
"version": "cloud" if api_key else "oss",
|
|
214
|
-
},
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
click.echo(
|
|
218
|
-
click.style(
|
|
219
|
-
f"Variant {variant_name} for App {app_name} added successfully to Agenta!",
|
|
220
|
-
fg="green",
|
|
221
|
-
)
|
|
222
|
-
)
|
|
223
|
-
# Last step us to save the config file
|
|
224
|
-
toml.dump(config, config_file.open("w"))
|
|
225
|
-
if overwrite:
|
|
226
|
-
# In the case we are overwriting, don't return anything. Otherwise the command server would attempt to start the container which would result in an error!!!
|
|
227
|
-
# TODO: Improve this stupid design
|
|
228
|
-
return None
|
|
229
|
-
else:
|
|
230
|
-
return variant_id
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
def start_variant(variant_id: str, app_folder: str, host: str):
|
|
234
|
-
"""
|
|
235
|
-
Starts a container for an existing variant
|
|
236
|
-
Args:
|
|
237
|
-
variant_name: the name of the variant
|
|
238
|
-
app_folder: the folder of the app
|
|
239
|
-
"""
|
|
240
|
-
app_folder = Path(app_folder)
|
|
241
|
-
config_file = app_folder / "config.toml"
|
|
242
|
-
config = toml.load(config_file)
|
|
243
|
-
app_id = config["app_id"]
|
|
244
|
-
api_key = config.get("api_key", "")
|
|
245
|
-
|
|
246
|
-
if len(config["variants"]) == 0:
|
|
247
|
-
click.echo("No variants found. Please add a variant first.")
|
|
248
|
-
return
|
|
249
|
-
|
|
250
|
-
if variant_id:
|
|
251
|
-
if variant_id not in config["variant_ids"]:
|
|
252
|
-
click.echo(
|
|
253
|
-
click.style(
|
|
254
|
-
f"Variant {variant_id} not found in backend. Maybe you removed it in the webUI?",
|
|
255
|
-
fg="red",
|
|
256
|
-
)
|
|
257
|
-
)
|
|
258
|
-
return
|
|
259
|
-
else:
|
|
260
|
-
variant_name = questionary.select(
|
|
261
|
-
"Please choose a variant", choices=config["variants"]
|
|
262
|
-
).ask()
|
|
263
|
-
variant_id = config["variant_ids"][config["variants"].index(variant_name)]
|
|
264
|
-
|
|
265
|
-
client = AgentaApi(
|
|
266
|
-
base_url=f"{host}/{BACKEND_URL_SUFFIX}",
|
|
267
|
-
api_key=api_key,
|
|
268
|
-
)
|
|
269
|
-
|
|
270
|
-
variant = client.variants.start_variant(
|
|
271
|
-
variant_id=variant_id,
|
|
272
|
-
action=VariantAction(action="START"),
|
|
273
|
-
)
|
|
274
|
-
endpoint = variant.uri
|
|
275
|
-
click.echo("\n" + click.style("Congratulations! 🎉", bold=True, fg="green"))
|
|
276
|
-
click.echo(
|
|
277
|
-
click.style("Your app has been deployed locally as an API. 🚀", fg="cyan")
|
|
278
|
-
+ click.style(" You can access it here: ", fg="white")
|
|
279
|
-
+ click.style(f"{endpoint}/", bold=True, fg="yellow")
|
|
280
|
-
)
|
|
281
|
-
|
|
282
|
-
click.echo(
|
|
283
|
-
click.style("\nRead the API documentation. 📚", fg="cyan")
|
|
284
|
-
+ click.style(" It's available at: ", fg="white")
|
|
285
|
-
+ click.style(f"{endpoint}/docs", bold=True, fg="yellow")
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
webui_host = "http://localhost" if host == "localhost" else host
|
|
289
|
-
click.echo(
|
|
290
|
-
click.style(
|
|
291
|
-
"\nStart experimenting with your app in the playground. 🎮",
|
|
292
|
-
fg="cyan",
|
|
293
|
-
)
|
|
294
|
-
+ click.style(" Go to: ", fg="white")
|
|
295
|
-
+ click.style(f"{webui_host}/apps/{app_id}/playground", bold=True, fg="yellow")
|
|
296
|
-
+ "\n"
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
def remove_variant(variant_name: str, app_folder: str, host: str):
|
|
301
|
-
"""
|
|
302
|
-
Removes a variant from the server
|
|
303
|
-
Args:
|
|
304
|
-
variant_name: the name of the variant
|
|
305
|
-
app_folder: the folder of the app
|
|
306
|
-
"""
|
|
307
|
-
config_file = Path(app_folder) / "config.toml"
|
|
308
|
-
config = toml.load(config_file)
|
|
309
|
-
app_name = config["app_name"]
|
|
310
|
-
api_key = config.get("api_key", "")
|
|
311
|
-
|
|
312
|
-
if not config["variants"]:
|
|
313
|
-
click.echo(
|
|
314
|
-
click.style(
|
|
315
|
-
f"No variants found for app {app_name}. Make sure you have deployed at least one variant.",
|
|
316
|
-
fg="red",
|
|
317
|
-
)
|
|
318
|
-
)
|
|
319
|
-
return
|
|
320
|
-
|
|
321
|
-
if variant_name:
|
|
322
|
-
if variant_name not in config["variants"]:
|
|
323
|
-
click.echo(
|
|
324
|
-
click.style(
|
|
325
|
-
f"Variant {variant_name} not found in backend. Maybe you already removed it in the webUI?",
|
|
326
|
-
fg="red",
|
|
327
|
-
)
|
|
328
|
-
)
|
|
329
|
-
return
|
|
330
|
-
else:
|
|
331
|
-
variant_name = questionary.select(
|
|
332
|
-
"Please choose a variant", choices=config["variants"]
|
|
333
|
-
).ask()
|
|
334
|
-
variant_id = config["variant_ids"][config["variants"].index(variant_name)]
|
|
335
|
-
|
|
336
|
-
client = AgentaApi(
|
|
337
|
-
base_url=f"{host}/{BACKEND_URL_SUFFIX}",
|
|
338
|
-
api_key=api_key,
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
try:
|
|
342
|
-
client.variants.remove_variant(variant_id=variant_id)
|
|
343
|
-
except Exception as ex:
|
|
344
|
-
click.echo(
|
|
345
|
-
click.style(
|
|
346
|
-
f"Error while removing variant {variant_name} for App {app_name} from the backend",
|
|
347
|
-
fg="red",
|
|
348
|
-
)
|
|
349
|
-
)
|
|
350
|
-
click.echo(click.style(f"Error message: {ex}", fg="red"))
|
|
351
|
-
return
|
|
352
|
-
|
|
353
|
-
click.echo(
|
|
354
|
-
click.style(
|
|
355
|
-
f"Variant {variant_name} for App {app_name} removed successfully from Agenta!",
|
|
356
|
-
fg="green",
|
|
357
|
-
)
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
def list_variants(app_folder: str, host: str):
|
|
362
|
-
"""List available variants for an app and print them to the console
|
|
363
|
-
|
|
364
|
-
Arguments:
|
|
365
|
-
app_folder -- _description_
|
|
366
|
-
"""
|
|
367
|
-
config_file = Path(app_folder) / "config.toml"
|
|
368
|
-
config = toml.load(config_file)
|
|
369
|
-
app_name = config["app_name"]
|
|
370
|
-
app_id = config["app_id"]
|
|
371
|
-
api_key = config.get("api_key", "")
|
|
372
|
-
variants = []
|
|
373
|
-
|
|
374
|
-
client = AgentaApi(
|
|
375
|
-
base_url=f"{host}/{BACKEND_URL_SUFFIX}",
|
|
376
|
-
api_key=api_key,
|
|
377
|
-
)
|
|
378
|
-
|
|
379
|
-
try:
|
|
380
|
-
variants: List[AppVariant] = client.apps.list_app_variants(app_id=app_id)
|
|
381
|
-
except Exception as ex:
|
|
382
|
-
raise ex
|
|
383
|
-
|
|
384
|
-
if variants:
|
|
385
|
-
for variant in variants:
|
|
386
|
-
helper.display_app_variant(variant)
|
|
387
|
-
else:
|
|
388
|
-
click.echo(click.style(f"No variants found for app {app_name}", fg="red"))
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
def config_check(app_folder: str):
|
|
392
|
-
"""Check the config file and update it from the backend
|
|
393
|
-
|
|
394
|
-
Arguments:
|
|
395
|
-
app_folder -- the app folder
|
|
396
|
-
"""
|
|
397
|
-
|
|
398
|
-
click.echo(click.style("\nChecking and updating config file...", fg="bright_black"))
|
|
399
|
-
app_folder = Path(app_folder)
|
|
400
|
-
config_file = app_folder / "config.toml"
|
|
401
|
-
if not config_file.exists():
|
|
402
|
-
click.echo(
|
|
403
|
-
click.style(
|
|
404
|
-
f"Config file not found in {app_folder}. Make sure you are in the right folder and that you have run agenta init first.",
|
|
405
|
-
fg="red",
|
|
406
|
-
)
|
|
407
|
-
)
|
|
408
|
-
return
|
|
409
|
-
host = get_host(app_folder) # TODO: Refactor the whole config thing
|
|
410
|
-
helper.update_config_from_backend(config_file, host=host)
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
def get_host(app_folder: str) -> str:
|
|
414
|
-
"""Fetches the host from the config"""
|
|
415
|
-
app_folder = Path(app_folder)
|
|
416
|
-
config_file = app_folder / "config.toml"
|
|
417
|
-
config = toml.load(config_file)
|
|
418
|
-
if "backend_host" not in config:
|
|
419
|
-
host = "http://localhost"
|
|
420
|
-
else:
|
|
421
|
-
host = config["backend_host"]
|
|
422
|
-
return host
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
@variant.command(name="remove")
|
|
426
|
-
@click.option("--app_folder", default=".")
|
|
427
|
-
@click.option("--variant_name", default="")
|
|
428
|
-
def remove_variant_cli(variant_name: str, app_folder: str):
|
|
429
|
-
"""Remove an existing variant."""
|
|
430
|
-
|
|
431
|
-
try:
|
|
432
|
-
config_check(app_folder)
|
|
433
|
-
remove_variant(
|
|
434
|
-
variant_name=variant_name,
|
|
435
|
-
app_folder=app_folder,
|
|
436
|
-
host=get_host(app_folder),
|
|
437
|
-
)
|
|
438
|
-
except Exception as ex:
|
|
439
|
-
click.echo(click.style(f"Error while removing variant: {ex}", fg="red"))
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
@variant.command(
|
|
443
|
-
name="serve",
|
|
444
|
-
context_settings=dict(
|
|
445
|
-
ignore_unknown_options=True,
|
|
446
|
-
allow_extra_args=True,
|
|
447
|
-
),
|
|
448
|
-
)
|
|
449
|
-
@click.option("--app_folder", default=".")
|
|
450
|
-
@click.option("--file_name", default=None, help="The name of the file to run")
|
|
451
|
-
@click.option(
|
|
452
|
-
"--overwrite",
|
|
453
|
-
is_flag=True,
|
|
454
|
-
help="Overwrite the existing variant if it exists",
|
|
455
|
-
)
|
|
456
|
-
@click.pass_context
|
|
457
|
-
def serve_cli(ctx, app_folder: str, file_name: str, overwrite: bool):
|
|
458
|
-
"""Adds a variant to the web UI and serves the API locally."""
|
|
459
|
-
|
|
460
|
-
if not file_name:
|
|
461
|
-
if ctx.args:
|
|
462
|
-
file_name = ctx.args[0]
|
|
463
|
-
else:
|
|
464
|
-
error_msg = "To serve variant, kindly provide the filename and run:\n"
|
|
465
|
-
error_msg += ">>> agenta variant serve --file_name <filename>.py\n"
|
|
466
|
-
error_msg += "or\n"
|
|
467
|
-
error_msg += ">>> agenta variant serve <filename>.py"
|
|
468
|
-
click.echo(click.style(f"{error_msg}", fg="red"))
|
|
469
|
-
sys.exit(1)
|
|
470
|
-
|
|
471
|
-
try:
|
|
472
|
-
config_check(app_folder)
|
|
473
|
-
except Exception as e:
|
|
474
|
-
click.echo(click.style("Failed during configuration check.", fg="red"))
|
|
475
|
-
click.echo(click.style(f"Error message: {str(e)}", fg="red"))
|
|
476
|
-
sys.exit(1)
|
|
477
|
-
|
|
478
|
-
try:
|
|
479
|
-
host = get_host(app_folder)
|
|
480
|
-
except Exception as e:
|
|
481
|
-
click.echo(click.style("Failed to retrieve the host.", fg="red"))
|
|
482
|
-
click.echo(click.style(f"Error message: {str(e)}", fg="red"))
|
|
483
|
-
sys.exit(1)
|
|
484
|
-
|
|
485
|
-
try:
|
|
486
|
-
api_key = helper.get_global_config("api_key")
|
|
487
|
-
except Exception as e:
|
|
488
|
-
click.echo(click.style("Failed to retrieve the api key.", fg="red"))
|
|
489
|
-
click.echo(click.style(f"Error message: {str(e)}", fg="red"))
|
|
490
|
-
sys.exit(1)
|
|
491
|
-
|
|
492
|
-
try:
|
|
493
|
-
variant_id = add_variant(
|
|
494
|
-
app_folder=app_folder, file_name=file_name, host=host, overwrite=overwrite
|
|
495
|
-
)
|
|
496
|
-
except Exception as e:
|
|
497
|
-
click.echo(click.style("Failed to add variant.", fg="red"))
|
|
498
|
-
click.echo(click.style(f"Error message: {str(e)}", fg="red"))
|
|
499
|
-
sys.exit(1)
|
|
500
|
-
|
|
501
|
-
if variant_id:
|
|
502
|
-
try:
|
|
503
|
-
start_variant(variant_id=variant_id, app_folder=app_folder, host=host)
|
|
504
|
-
except ConnectionError:
|
|
505
|
-
error_msg = "Failed to connect to Agenta backend. Here's how you can solve the issue:\n"
|
|
506
|
-
error_msg += "- First, please ensure that the backend service is running and accessible.\n"
|
|
507
|
-
error_msg += (
|
|
508
|
-
"- Second, try restarting the containers (if using Docker Compose)."
|
|
509
|
-
)
|
|
510
|
-
click.echo(click.style(f"{error_msg}", fg="red"))
|
|
511
|
-
sys.exit(1)
|
|
512
|
-
except Exception as e:
|
|
513
|
-
click.echo(click.style("Failed to start container with LLM app.", fg="red"))
|
|
514
|
-
click.echo(click.style(f"Error message: {str(e)}", fg="red"))
|
|
515
|
-
sys.exit(1)
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
@variant.command(name="list")
|
|
519
|
-
@click.option("--app_folder", default=".")
|
|
520
|
-
def list_variants_cli(app_folder: str):
|
|
521
|
-
"""List the variants in the backend"""
|
|
522
|
-
try:
|
|
523
|
-
config_check(app_folder)
|
|
524
|
-
list_variants(app_folder=app_folder, host=get_host(app_folder))
|
|
525
|
-
except Exception as ex:
|
|
526
|
-
click.echo(click.style(f"Error while listing variants: {ex}", fg="red"))
|
agenta/cli/variant_configs.py
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
from agenta.cli import helper
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@click.group()
|
|
6
|
-
def config():
|
|
7
|
-
"""Commands for variants configurations"""
|
|
8
|
-
pass
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def update_backend_host(backend_host: str):
|
|
12
|
-
"""Check the config file and update the backend URL
|
|
13
|
-
|
|
14
|
-
Arguments:
|
|
15
|
-
app_folder -- the app folder
|
|
16
|
-
backend_host -- the backend host
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
click.echo(
|
|
20
|
-
click.style("\nChecking and updating global backend host...", fg="bright_black")
|
|
21
|
-
)
|
|
22
|
-
helper.set_global_config("host", backend_host)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@config.command(
|
|
26
|
-
name="set-host",
|
|
27
|
-
context_settings=dict(
|
|
28
|
-
ignore_unknown_options=True,
|
|
29
|
-
allow_extra_args=True,
|
|
30
|
-
),
|
|
31
|
-
)
|
|
32
|
-
@click.option(
|
|
33
|
-
"--backend_host", default=None, help="The URL of the backend host to use."
|
|
34
|
-
)
|
|
35
|
-
@click.pass_context
|
|
36
|
-
def set_config_url(ctx, backend_host: str):
|
|
37
|
-
"""Set the backend URL in the app configuration"""
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
if not backend_host:
|
|
41
|
-
if ctx.args:
|
|
42
|
-
backend_host = ctx.args[0]
|
|
43
|
-
else:
|
|
44
|
-
click.echo(click.style("Backend host URL not specified", fg="red"))
|
|
45
|
-
|
|
46
|
-
update_backend_host(backend_host)
|
|
47
|
-
click.echo(click.style("Backend host updated successfully! 🎉\n"))
|
|
48
|
-
except Exception as ex:
|
|
49
|
-
click.echo(click.style(f"Error updating backend host: {ex}", fg="red"))
|
agenta/client/api.py
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import toml
|
|
3
|
-
import time
|
|
4
|
-
import click
|
|
5
|
-
from typing import Dict
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from agenta.client.backend import client
|
|
8
|
-
from agenta.client.api_models import Image
|
|
9
|
-
from requests.exceptions import RequestException
|
|
10
|
-
from agenta.client.backend.client import AgentaApi
|
|
11
|
-
from agenta.client.exceptions import APIRequestError
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def add_variant_to_server(
|
|
15
|
-
app_id: str,
|
|
16
|
-
base_name: str,
|
|
17
|
-
image: Image,
|
|
18
|
-
backend_url: str,
|
|
19
|
-
api_key: str,
|
|
20
|
-
retries=10,
|
|
21
|
-
backoff_factor=1,
|
|
22
|
-
) -> Dict:
|
|
23
|
-
"""
|
|
24
|
-
Adds a variant to the server with a retry mechanism and a single-line loading state.
|
|
25
|
-
|
|
26
|
-
Args:
|
|
27
|
-
app_id (str): The ID of the app to add the variant to.
|
|
28
|
-
base_name (str): The base name for the variant.
|
|
29
|
-
image (Image): The image to use for the variant.
|
|
30
|
-
retries (int): Number of times to retry the request.
|
|
31
|
-
backoff_factor (float): Factor to determine the delay between retries (exponential backoff).
|
|
32
|
-
|
|
33
|
-
Returns:
|
|
34
|
-
dict: The JSON response from the server.
|
|
35
|
-
|
|
36
|
-
Raises:
|
|
37
|
-
APIRequestError: If the request to the server fails after retrying.
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
click.echo(
|
|
41
|
-
click.style("Waiting for the variant to be ready", fg="yellow"), nl=False
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
client = AgentaApi(
|
|
45
|
-
base_url=backend_url,
|
|
46
|
-
api_key=api_key,
|
|
47
|
-
)
|
|
48
|
-
for attempt in range(retries):
|
|
49
|
-
try:
|
|
50
|
-
response = client.apps.add_variant_from_image(
|
|
51
|
-
app_id=app_id,
|
|
52
|
-
variant_name=f"{base_name.lower()}.default",
|
|
53
|
-
base_name=base_name,
|
|
54
|
-
config_name="default",
|
|
55
|
-
docker_id=image.docker_id,
|
|
56
|
-
tags=image.tags,
|
|
57
|
-
)
|
|
58
|
-
click.echo(click.style("\nVariant added successfully!", fg="green"))
|
|
59
|
-
return response
|
|
60
|
-
except RequestException as e:
|
|
61
|
-
if attempt < retries - 1:
|
|
62
|
-
click.echo(click.style(".", fg="yellow"), nl=False)
|
|
63
|
-
time.sleep(backoff_factor * (2**attempt))
|
|
64
|
-
else:
|
|
65
|
-
raise APIRequestError(
|
|
66
|
-
click.style(
|
|
67
|
-
f"\nRequest to app_variant endpoint failed with status code {response.status_code} and error message: {e}.",
|
|
68
|
-
fg="red",
|
|
69
|
-
)
|
|
70
|
-
)
|
|
71
|
-
except Exception as e:
|
|
72
|
-
raise APIRequestError(
|
|
73
|
-
click.style(f"\nAn unexpected error occurred: {e}", fg="red")
|
|
74
|
-
)
|
agenta/client/api_models.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
from pydantic import BaseModel
|
|
2
|
-
from typing import List, Optional, Dict, Any
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class AppVariant(BaseModel):
|
|
6
|
-
app_id: str
|
|
7
|
-
app_name: str
|
|
8
|
-
variant_name: str
|
|
9
|
-
variant_id: str
|
|
10
|
-
parameters: Optional[Dict[str, Any]]
|
|
11
|
-
previous_variant_name: Optional[str]
|
|
12
|
-
base_name: Optional[str]
|
|
13
|
-
config_name: Optional[str]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Variant(BaseModel):
|
|
17
|
-
variant_id: str
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class Image(BaseModel):
|
|
21
|
-
type: Optional[str]
|
|
22
|
-
docker_id: str
|
|
23
|
-
tags: str
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class URI(BaseModel):
|
|
27
|
-
uri: str
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class VariantConfigPayload(BaseModel):
|
|
31
|
-
base_id: str
|
|
32
|
-
config_name: str
|
|
33
|
-
parameters: Dict[str, Any]
|
|
34
|
-
overwrite: bool
|