promptic-sdk 0.2.0__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.
- promptic_sdk/__init__.py +97 -0
- promptic_sdk/cli/__init__.py +28 -0
- promptic_sdk/cli/commands/__init__.py +0 -0
- promptic_sdk/cli/commands/annotations.py +126 -0
- promptic_sdk/cli/commands/components.py +106 -0
- promptic_sdk/cli/commands/configure.py +25 -0
- promptic_sdk/cli/commands/datasets.py +134 -0
- promptic_sdk/cli/commands/deployments.py +103 -0
- promptic_sdk/cli/commands/evaluations.py +196 -0
- promptic_sdk/cli/commands/evaluators.py +106 -0
- promptic_sdk/cli/commands/experiments.py +228 -0
- promptic_sdk/cli/commands/iterations.py +121 -0
- promptic_sdk/cli/commands/login.py +161 -0
- promptic_sdk/cli/commands/observations.py +158 -0
- promptic_sdk/cli/commands/runs.py +128 -0
- promptic_sdk/cli/commands/traces.py +164 -0
- promptic_sdk/cli/commands/workspace.py +102 -0
- promptic_sdk/cli/config.py +116 -0
- promptic_sdk/cli/main.py +67 -0
- promptic_sdk/client.py +1013 -0
- promptic_sdk/models.py +488 -0
- promptic_sdk/py.typed +0 -0
- promptic_sdk/tracing.py +377 -0
- promptic_sdk-0.2.0.dist-info/METADATA +255 -0
- promptic_sdk-0.2.0.dist-info/RECORD +28 -0
- promptic_sdk-0.2.0.dist-info/WHEEL +4 -0
- promptic_sdk-0.2.0.dist-info/entry_points.txt +3 -0
- promptic_sdk-0.2.0.dist-info/licenses/LICENSE +21 -0
promptic_sdk/__init__.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Promptic Python SDK."""
|
|
2
|
+
|
|
3
|
+
from promptic_sdk.client import AsyncPrompticClient, PrompticAPIError, PrompticClient
|
|
4
|
+
from promptic_sdk.models import (
|
|
5
|
+
AgentEvaluation,
|
|
6
|
+
AgentEvaluationList,
|
|
7
|
+
AgentEvaluationStatus,
|
|
8
|
+
Component,
|
|
9
|
+
ComponentCreated,
|
|
10
|
+
ComponentList,
|
|
11
|
+
Dataset,
|
|
12
|
+
DatasetItem,
|
|
13
|
+
DatasetList,
|
|
14
|
+
DatasetWithItems,
|
|
15
|
+
DeployedPrompt,
|
|
16
|
+
Deployment,
|
|
17
|
+
DeploymentCreated,
|
|
18
|
+
Evaluator,
|
|
19
|
+
EvaluatorList,
|
|
20
|
+
EvaluatorType,
|
|
21
|
+
Experiment,
|
|
22
|
+
ExperimentList,
|
|
23
|
+
ExperimentStarted,
|
|
24
|
+
ExperimentStatus,
|
|
25
|
+
Hyperparameters,
|
|
26
|
+
Insight,
|
|
27
|
+
InsightResult,
|
|
28
|
+
InsightResultMeta,
|
|
29
|
+
Iteration,
|
|
30
|
+
IterationList,
|
|
31
|
+
IterationScore,
|
|
32
|
+
IterationWithScores,
|
|
33
|
+
ModelProvider,
|
|
34
|
+
Observation,
|
|
35
|
+
ObservationList,
|
|
36
|
+
OptimizerType,
|
|
37
|
+
Span,
|
|
38
|
+
SpanEvent,
|
|
39
|
+
TaskType,
|
|
40
|
+
Trace,
|
|
41
|
+
TraceList,
|
|
42
|
+
TraceListItem,
|
|
43
|
+
TracingStats,
|
|
44
|
+
Workspace,
|
|
45
|
+
)
|
|
46
|
+
from promptic_sdk.tracing import ai_component, dataset, init
|
|
47
|
+
|
|
48
|
+
__version__ = "0.2.0"
|
|
49
|
+
__all__ = [
|
|
50
|
+
"AsyncPrompticClient",
|
|
51
|
+
"PrompticClient",
|
|
52
|
+
"PrompticAPIError",
|
|
53
|
+
"ai_component",
|
|
54
|
+
"dataset",
|
|
55
|
+
"init",
|
|
56
|
+
# Models
|
|
57
|
+
"AgentEvaluation",
|
|
58
|
+
"AgentEvaluationList",
|
|
59
|
+
"AgentEvaluationStatus",
|
|
60
|
+
"Component",
|
|
61
|
+
"ComponentCreated",
|
|
62
|
+
"ComponentList",
|
|
63
|
+
"Dataset",
|
|
64
|
+
"DatasetItem",
|
|
65
|
+
"DatasetList",
|
|
66
|
+
"DatasetWithItems",
|
|
67
|
+
"DeployedPrompt",
|
|
68
|
+
"Deployment",
|
|
69
|
+
"DeploymentCreated",
|
|
70
|
+
"Evaluator",
|
|
71
|
+
"EvaluatorList",
|
|
72
|
+
"EvaluatorType",
|
|
73
|
+
"Experiment",
|
|
74
|
+
"ExperimentList",
|
|
75
|
+
"ExperimentStarted",
|
|
76
|
+
"ExperimentStatus",
|
|
77
|
+
"Hyperparameters",
|
|
78
|
+
"Insight",
|
|
79
|
+
"InsightResult",
|
|
80
|
+
"InsightResultMeta",
|
|
81
|
+
"Iteration",
|
|
82
|
+
"IterationList",
|
|
83
|
+
"IterationScore",
|
|
84
|
+
"IterationWithScores",
|
|
85
|
+
"ModelProvider",
|
|
86
|
+
"Observation",
|
|
87
|
+
"ObservationList",
|
|
88
|
+
"OptimizerType",
|
|
89
|
+
"Span",
|
|
90
|
+
"SpanEvent",
|
|
91
|
+
"TaskType",
|
|
92
|
+
"Trace",
|
|
93
|
+
"TraceList",
|
|
94
|
+
"TraceListItem",
|
|
95
|
+
"TracingStats",
|
|
96
|
+
"Workspace",
|
|
97
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Promptic CLI package."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
from promptic_sdk.cli.config import load_config
|
|
9
|
+
from promptic_sdk.client import PrompticClient
|
|
10
|
+
|
|
11
|
+
_err_console = Console(stderr=True)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_client() -> PrompticClient:
|
|
15
|
+
"""Create an authenticated client from CLI config."""
|
|
16
|
+
config = load_config()
|
|
17
|
+
if not config:
|
|
18
|
+
_err_console.print(
|
|
19
|
+
"No configuration found. Run 'promptic login' or 'promptic configure'.",
|
|
20
|
+
style="red",
|
|
21
|
+
)
|
|
22
|
+
raise typer.Exit(1)
|
|
23
|
+
return PrompticClient(
|
|
24
|
+
api_key=config.api_key,
|
|
25
|
+
access_token=config.access_token,
|
|
26
|
+
workspace_id=config.workspace_id,
|
|
27
|
+
endpoint=config.endpoint,
|
|
28
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Annotations commands — create, list, and delete."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import sys
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
|
|
13
|
+
from promptic_sdk.cli import get_client
|
|
14
|
+
from promptic_sdk.models import Annotation
|
|
15
|
+
|
|
16
|
+
annotations_app = typer.Typer(help="Manage trace annotations.")
|
|
17
|
+
console = Console()
|
|
18
|
+
err_console = Console(stderr=True)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@annotations_app.command("create")
|
|
22
|
+
def create_annotation(
|
|
23
|
+
component_id: str = typer.Option(..., "--component", help="AI Component ID."),
|
|
24
|
+
run_id: str = typer.Option(..., "--run", help="Run ID."),
|
|
25
|
+
trace_db_id: str = typer.Option(..., "--trace", help="Trace DB ID."),
|
|
26
|
+
rating: Annotated[
|
|
27
|
+
str | None,
|
|
28
|
+
typer.Option(help="Rating (positive/negative)."),
|
|
29
|
+
] = None,
|
|
30
|
+
comment: Annotated[str | None, typer.Option(help="Comment text.")] = None,
|
|
31
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Create or update an annotation for a trace in a run."""
|
|
34
|
+
with get_client() as client:
|
|
35
|
+
result = client.upsert_annotation(
|
|
36
|
+
component_id,
|
|
37
|
+
run_id,
|
|
38
|
+
trace_db_id,
|
|
39
|
+
rating=rating,
|
|
40
|
+
comment=comment,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if output_json:
|
|
44
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
45
|
+
sys.stdout.write("\n")
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
console.print(f"[green]Annotation saved:[/green] {result['id']}")
|
|
49
|
+
if result.get("rating"):
|
|
50
|
+
console.print(f" Rating: {result['rating']}")
|
|
51
|
+
if result.get("comment"):
|
|
52
|
+
console.print(f" Comment: {result['comment']}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _print_annotations_table(annotations: list[Annotation], title: str) -> None:
|
|
56
|
+
"""Shared helper to print an annotations table."""
|
|
57
|
+
if not annotations:
|
|
58
|
+
console.print("No annotations found.", style="dim")
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
table = Table(title=title)
|
|
62
|
+
table.add_column("ID", style="cyan", no_wrap=True)
|
|
63
|
+
table.add_column("Trace ID")
|
|
64
|
+
table.add_column("Rating")
|
|
65
|
+
table.add_column("Comment", max_width=40)
|
|
66
|
+
table.add_column("Created")
|
|
67
|
+
|
|
68
|
+
for ann in annotations:
|
|
69
|
+
table.add_row(
|
|
70
|
+
ann["id"],
|
|
71
|
+
ann["traceDbId"],
|
|
72
|
+
ann.get("rating") or "-",
|
|
73
|
+
(ann.get("comment") or "-")[:80],
|
|
74
|
+
ann["createdAt"],
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
console.print(table)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@annotations_app.command("list")
|
|
81
|
+
def list_annotations(
|
|
82
|
+
component_id: str = typer.Option(..., "--component", help="AI Component ID."),
|
|
83
|
+
run_id: Annotated[
|
|
84
|
+
str | None,
|
|
85
|
+
typer.Option("--run", help="Run ID (includes all annotations from the dataset)."),
|
|
86
|
+
] = None,
|
|
87
|
+
dataset_id: Annotated[
|
|
88
|
+
str | None,
|
|
89
|
+
typer.Option("--dataset", help="Dataset ID (all annotations across runs)."),
|
|
90
|
+
] = None,
|
|
91
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
92
|
+
) -> None:
|
|
93
|
+
"""List annotations for a run or dataset.
|
|
94
|
+
|
|
95
|
+
When using --run, returns all annotations across all runs of the same dataset.
|
|
96
|
+
When using --dataset, returns all annotations for traces in any run of that dataset.
|
|
97
|
+
"""
|
|
98
|
+
if not run_id and not dataset_id:
|
|
99
|
+
err_console.print("[red]Provide --run or --dataset.[/red]")
|
|
100
|
+
raise typer.Exit(1)
|
|
101
|
+
|
|
102
|
+
with get_client() as client:
|
|
103
|
+
if dataset_id:
|
|
104
|
+
result = client.list_dataset_annotations(component_id, dataset_id)
|
|
105
|
+
else:
|
|
106
|
+
result = client.list_annotations(component_id, run_id) # type: ignore[arg-type]
|
|
107
|
+
|
|
108
|
+
if output_json:
|
|
109
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
110
|
+
sys.stdout.write("\n")
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
annotations = result["data"]
|
|
114
|
+
_print_annotations_table(annotations, f"Annotations ({len(annotations)})")
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@annotations_app.command("delete")
|
|
118
|
+
def delete_annotation(
|
|
119
|
+
annotation_id: str = typer.Argument(help="Annotation ID."),
|
|
120
|
+
component_id: str = typer.Option(..., "--component", help="AI Component ID."),
|
|
121
|
+
run_id: str = typer.Option(..., "--run", help="Run ID."),
|
|
122
|
+
) -> None:
|
|
123
|
+
"""Delete an annotation."""
|
|
124
|
+
with get_client() as client:
|
|
125
|
+
client.delete_annotation(component_id, run_id, annotation_id)
|
|
126
|
+
console.print("[green]Annotation deleted.[/green]")
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""AI component commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
|
|
12
|
+
from promptic_sdk.cli import get_client
|
|
13
|
+
|
|
14
|
+
components_app = typer.Typer(help="Manage AI components.")
|
|
15
|
+
console = Console()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@components_app.command("list")
|
|
19
|
+
def list_components(
|
|
20
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
21
|
+
) -> None:
|
|
22
|
+
"""List all AI components in the workspace."""
|
|
23
|
+
with get_client() as client:
|
|
24
|
+
result = client.list_components()
|
|
25
|
+
|
|
26
|
+
if output_json:
|
|
27
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
28
|
+
sys.stdout.write("\n")
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
items = result["data"]
|
|
32
|
+
if not items:
|
|
33
|
+
console.print("No components found.", style="dim")
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
table = Table(title=f"AI Components ({len(items)})")
|
|
37
|
+
table.add_column("ID", style="cyan", no_wrap=True)
|
|
38
|
+
table.add_column("Name")
|
|
39
|
+
table.add_column("Description")
|
|
40
|
+
table.add_column("Created")
|
|
41
|
+
|
|
42
|
+
for c in items:
|
|
43
|
+
table.add_row(
|
|
44
|
+
c["id"],
|
|
45
|
+
c["name"],
|
|
46
|
+
c["description"] or "-",
|
|
47
|
+
c["createdAt"],
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
console.print(table)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@components_app.command("create")
|
|
54
|
+
def create_component(
|
|
55
|
+
name: str = typer.Argument(help="Component name."),
|
|
56
|
+
description: str | None = typer.Option(
|
|
57
|
+
None, "--description", "-d", help="Optional description."
|
|
58
|
+
),
|
|
59
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
60
|
+
) -> None:
|
|
61
|
+
"""Create a new AI component."""
|
|
62
|
+
with get_client() as client:
|
|
63
|
+
result = client.create_component(name, description=description)
|
|
64
|
+
|
|
65
|
+
if output_json:
|
|
66
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
67
|
+
sys.stdout.write("\n")
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
console.print(f"[green]Component created:[/green] {result['id']}")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@components_app.command("get")
|
|
74
|
+
def get_component(
|
|
75
|
+
component_id: str = typer.Argument(help="Component ID."),
|
|
76
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
77
|
+
) -> None:
|
|
78
|
+
"""Get details of an AI component."""
|
|
79
|
+
with get_client() as client:
|
|
80
|
+
result = client.get_component(component_id)
|
|
81
|
+
|
|
82
|
+
if output_json:
|
|
83
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
84
|
+
sys.stdout.write("\n")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
console.print(f"\n[bold]Component:[/bold] {result['name']}")
|
|
88
|
+
console.print(f" ID: {result['id']}")
|
|
89
|
+
if result["description"]:
|
|
90
|
+
console.print(f" Description: {result['description']}")
|
|
91
|
+
console.print(f" Created: {result['createdAt']}")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@components_app.command("delete")
|
|
95
|
+
def delete_component(
|
|
96
|
+
component_id: str = typer.Argument(help="Component ID."),
|
|
97
|
+
force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation."),
|
|
98
|
+
) -> None:
|
|
99
|
+
"""Delete an AI component."""
|
|
100
|
+
if not force:
|
|
101
|
+
typer.confirm(f"Delete component {component_id}?", abort=True)
|
|
102
|
+
|
|
103
|
+
with get_client() as client:
|
|
104
|
+
client.delete_component(component_id)
|
|
105
|
+
|
|
106
|
+
console.print("[green]Component deleted.[/green]")
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Configure command — save API key and endpoint."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
from promptic_sdk.cli.config import get_config_path, save_config
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def configure(
|
|
14
|
+
api_key: str = typer.Option(
|
|
15
|
+
..., prompt="Promptic API key", help="Your Promptic API key (pk_...)."
|
|
16
|
+
),
|
|
17
|
+
endpoint: str = typer.Option(
|
|
18
|
+
"https://promptic.eu",
|
|
19
|
+
prompt="Promptic endpoint",
|
|
20
|
+
help="Promptic platform URL.",
|
|
21
|
+
),
|
|
22
|
+
) -> None:
|
|
23
|
+
"""Save Promptic API key and endpoint to ~/.promptic/config.toml."""
|
|
24
|
+
save_config(api_key, endpoint)
|
|
25
|
+
console.print(f"Configuration saved to {get_config_path()}", style="green")
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""Datasets commands — create, list, and get."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import sys
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
|
|
13
|
+
from promptic_sdk.cli import get_client
|
|
14
|
+
|
|
15
|
+
datasets_app = typer.Typer(help="Manage agent datasets.")
|
|
16
|
+
console = Console()
|
|
17
|
+
err_console = Console(stderr=True)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@datasets_app.command("create")
|
|
21
|
+
def create_dataset(
|
|
22
|
+
component_id: str = typer.Option(..., "--component", help="AI Component ID."),
|
|
23
|
+
name: str = typer.Option(..., "--name", help="Dataset name."),
|
|
24
|
+
description: Annotated[str | None, typer.Option(help="Dataset description.")] = None,
|
|
25
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
26
|
+
) -> None:
|
|
27
|
+
"""Create a new dataset from traces."""
|
|
28
|
+
with get_client() as client:
|
|
29
|
+
# First create the dataset
|
|
30
|
+
result = client.create_dataset(
|
|
31
|
+
component_id,
|
|
32
|
+
name,
|
|
33
|
+
description=description,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
if output_json:
|
|
37
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
38
|
+
sys.stdout.write("\n")
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
console.print(f"[green]Dataset created:[/green] {result['name']}")
|
|
42
|
+
console.print(f" ID: {result['id']}")
|
|
43
|
+
console.print(f" Items: {result['itemCount']}")
|
|
44
|
+
console.print()
|
|
45
|
+
console.print(
|
|
46
|
+
"[dim]Tip: Add traces via SDK with "
|
|
47
|
+
"promptic_sdk.ai_component('...', dataset='...')"
|
|
48
|
+
" or use the API.[/dim]"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@datasets_app.command("list")
|
|
53
|
+
def list_datasets(
|
|
54
|
+
component_id: str = typer.Option(..., "--component", help="AI Component ID."),
|
|
55
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
56
|
+
) -> None:
|
|
57
|
+
"""List datasets for an AI component."""
|
|
58
|
+
with get_client() as client:
|
|
59
|
+
result = client.list_datasets(component_id)
|
|
60
|
+
|
|
61
|
+
if output_json:
|
|
62
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
63
|
+
sys.stdout.write("\n")
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
datasets = result["data"]
|
|
67
|
+
if not datasets:
|
|
68
|
+
console.print("No datasets found.", style="dim")
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
table = Table(title=f"Datasets ({len(datasets)})")
|
|
72
|
+
table.add_column("ID", style="cyan", no_wrap=True)
|
|
73
|
+
table.add_column("Name")
|
|
74
|
+
table.add_column("Items", justify="right")
|
|
75
|
+
table.add_column("Created")
|
|
76
|
+
|
|
77
|
+
for ds in datasets:
|
|
78
|
+
table.add_row(
|
|
79
|
+
ds["id"],
|
|
80
|
+
ds["name"],
|
|
81
|
+
str(ds["itemCount"]),
|
|
82
|
+
ds["createdAt"],
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
console.print(table)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@datasets_app.command("get")
|
|
89
|
+
def get_dataset(
|
|
90
|
+
dataset_id: str = typer.Argument(help="Dataset ID."),
|
|
91
|
+
component_id: str = typer.Option(..., "--component", help="AI Component ID."),
|
|
92
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
93
|
+
) -> None:
|
|
94
|
+
"""Get a dataset with its items."""
|
|
95
|
+
with get_client() as client:
|
|
96
|
+
result = client.get_dataset(component_id, dataset_id)
|
|
97
|
+
|
|
98
|
+
if output_json:
|
|
99
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
100
|
+
sys.stdout.write("\n")
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
console.print(f"\n[bold]Dataset:[/bold] {result['name']}")
|
|
104
|
+
console.print(f"[bold]ID:[/bold] {result['id']}")
|
|
105
|
+
console.print(f"[bold]Items:[/bold] {result['itemCount']}")
|
|
106
|
+
if result.get("description"):
|
|
107
|
+
console.print(f"[bold]Description:[/bold] {result['description']}")
|
|
108
|
+
|
|
109
|
+
items = result.get("items", [])
|
|
110
|
+
if items:
|
|
111
|
+
console.print(f"\n[bold]Items ({len(items)}):[/bold]")
|
|
112
|
+
item_table = Table()
|
|
113
|
+
item_table.add_column("Trace ID", style="cyan")
|
|
114
|
+
item_table.add_column("Input", max_width=40)
|
|
115
|
+
item_table.add_column("Output", max_width=40)
|
|
116
|
+
|
|
117
|
+
for item in items:
|
|
118
|
+
item_table.add_row(
|
|
119
|
+
item["traceDbId"],
|
|
120
|
+
(item["input"] or "-")[:80],
|
|
121
|
+
(item["output"] or "-")[:80],
|
|
122
|
+
)
|
|
123
|
+
console.print(item_table)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@datasets_app.command("delete")
|
|
127
|
+
def delete_dataset(
|
|
128
|
+
dataset_id: str = typer.Argument(help="Dataset ID."),
|
|
129
|
+
component_id: str = typer.Option(..., "--component", help="AI Component ID."),
|
|
130
|
+
) -> None:
|
|
131
|
+
"""Delete a dataset."""
|
|
132
|
+
with get_client() as client:
|
|
133
|
+
client.delete_dataset(component_id, dataset_id)
|
|
134
|
+
console.print("[green]Dataset deleted.[/green]")
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Deployment commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
|
|
11
|
+
from promptic_sdk.cli import get_client
|
|
12
|
+
|
|
13
|
+
deployments_app = typer.Typer(help="Manage deployments.")
|
|
14
|
+
console = Console()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@deployments_app.command("status")
|
|
18
|
+
def deployment_status(
|
|
19
|
+
component_id: str = typer.Argument(help="Component ID."),
|
|
20
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
21
|
+
) -> None:
|
|
22
|
+
"""Show current deployment for a component."""
|
|
23
|
+
with get_client() as client:
|
|
24
|
+
result = client.get_deployment(component_id)
|
|
25
|
+
|
|
26
|
+
if output_json:
|
|
27
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
28
|
+
sys.stdout.write("\n")
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
if not result:
|
|
32
|
+
console.print("No deployment active.", style="dim")
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
exp = result["experiment"]
|
|
36
|
+
console.print("\n[bold]Active Deployment[/bold]")
|
|
37
|
+
console.print(f" Component: {result['aiComponentId']}")
|
|
38
|
+
console.print(f" Experiment: {result['experimentId']}")
|
|
39
|
+
console.print(f" Exp. Name: {exp['name'] or '-'}")
|
|
40
|
+
console.print(f" Model: {exp['targetModel']}")
|
|
41
|
+
console.print(f" Status: {exp['experimentStatus']}")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@deployments_app.command("deploy")
|
|
45
|
+
def deploy(
|
|
46
|
+
component_id: str = typer.Argument(help="Component ID."),
|
|
47
|
+
experiment_id: str = typer.Argument(help="Experiment ID to deploy."),
|
|
48
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
49
|
+
) -> None:
|
|
50
|
+
"""Deploy an experiment to a component."""
|
|
51
|
+
with get_client() as client:
|
|
52
|
+
result = client.deploy(component_id, experiment_id)
|
|
53
|
+
|
|
54
|
+
if output_json:
|
|
55
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
56
|
+
sys.stdout.write("\n")
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
console.print(
|
|
60
|
+
f"[green]Deployed[/green] experiment {result['experimentId']} "
|
|
61
|
+
f"to component {result['aiComponentId']}"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@deployments_app.command("prompt")
|
|
66
|
+
def deployment_prompt(
|
|
67
|
+
component_id: str = typer.Argument(help="Component ID."),
|
|
68
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
69
|
+
) -> None:
|
|
70
|
+
"""Show the deployed prompt for a component."""
|
|
71
|
+
with get_client() as client:
|
|
72
|
+
result = client.get_deployed_prompt(component_id)
|
|
73
|
+
|
|
74
|
+
if output_json:
|
|
75
|
+
json.dump(result, sys.stdout, indent=2, default=str)
|
|
76
|
+
sys.stdout.write("\n")
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
if not result:
|
|
80
|
+
console.print("No deployment active.", style="dim")
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
console.print(f"\n[bold]{result['componentName'] or '-'}[/bold]")
|
|
84
|
+
console.print(f" Model: {result['model']}")
|
|
85
|
+
console.print(f" Score: {result['score']}")
|
|
86
|
+
console.print(f" Experiment: {result['experimentId']}")
|
|
87
|
+
console.print("\n[bold]Prompt:[/bold]\n")
|
|
88
|
+
console.print(result["prompt"])
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@deployments_app.command("undeploy")
|
|
92
|
+
def undeploy(
|
|
93
|
+
component_id: str = typer.Argument(help="Component ID."),
|
|
94
|
+
force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation."),
|
|
95
|
+
) -> None:
|
|
96
|
+
"""Remove deployment from a component."""
|
|
97
|
+
if not force:
|
|
98
|
+
typer.confirm(f"Undeploy from component {component_id}?", abort=True)
|
|
99
|
+
|
|
100
|
+
with get_client() as client:
|
|
101
|
+
client.undeploy(component_id)
|
|
102
|
+
|
|
103
|
+
console.print("[green]Deployment removed.[/green]")
|