@arizeai/phoenix-cli 0.0.4 → 0.2.0
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.
- package/README.md +279 -16
- package/build/cli.d.ts.map +1 -0
- package/build/cli.js +25 -0
- package/build/cli.js.map +1 -0
- package/build/client.d.ts +49 -0
- package/build/client.d.ts.map +1 -0
- package/build/client.js +96 -0
- package/build/client.js.map +1 -0
- package/build/commands/dataset.d.ts +6 -0
- package/build/commands/dataset.d.ts.map +1 -0
- package/build/commands/dataset.js +153 -0
- package/build/commands/dataset.js.map +1 -0
- package/build/commands/datasets.d.ts +6 -0
- package/build/commands/datasets.d.ts.map +1 -0
- package/build/commands/datasets.js +97 -0
- package/build/commands/datasets.js.map +1 -0
- package/build/commands/experiment.d.ts +6 -0
- package/build/commands/experiment.d.ts.map +1 -0
- package/build/commands/experiment.js +106 -0
- package/build/commands/experiment.js.map +1 -0
- package/build/commands/experiments.d.ts +6 -0
- package/build/commands/experiments.d.ts.map +1 -0
- package/build/commands/experiments.js +201 -0
- package/build/commands/experiments.js.map +1 -0
- package/build/commands/formatDataset.d.ts +26 -0
- package/build/commands/formatDataset.d.ts.map +1 -0
- package/build/commands/formatDataset.js +60 -0
- package/build/commands/formatDataset.js.map +1 -0
- package/build/commands/formatDatasets.d.ts +27 -0
- package/build/commands/formatDatasets.d.ts.map +1 -0
- package/build/commands/formatDatasets.js +76 -0
- package/build/commands/formatDatasets.js.map +1 -0
- package/build/commands/formatExperiment.d.ts +35 -0
- package/build/commands/formatExperiment.d.ts.map +1 -0
- package/build/commands/formatExperiment.js +191 -0
- package/build/commands/formatExperiment.js.map +1 -0
- package/build/commands/formatExperiments.d.ts +16 -0
- package/build/commands/formatExperiments.d.ts.map +1 -0
- package/build/commands/formatExperiments.js +53 -0
- package/build/commands/formatExperiments.js.map +1 -0
- package/build/commands/formatProjects.d.ts +19 -0
- package/build/commands/formatProjects.d.ts.map +1 -0
- package/build/commands/formatProjects.js +21 -0
- package/build/commands/formatProjects.js.map +1 -0
- package/build/commands/formatTraces.d.ts +25 -0
- package/build/commands/formatTraces.d.ts.map +1 -0
- package/build/commands/formatTraces.js +165 -0
- package/build/commands/formatTraces.js.map +1 -0
- package/build/commands/index.d.ts +8 -0
- package/build/commands/index.d.ts.map +1 -0
- package/build/commands/index.js +8 -0
- package/build/commands/index.js.map +1 -0
- package/build/commands/projects.d.ts +6 -0
- package/build/commands/projects.d.ts.map +1 -0
- package/build/commands/projects.js +87 -0
- package/build/commands/projects.js.map +1 -0
- package/build/commands/trace.d.ts +6 -0
- package/build/commands/trace.d.ts.map +1 -0
- package/build/commands/trace.js +143 -0
- package/build/commands/trace.js.map +1 -0
- package/build/commands/traces.d.ts +6 -0
- package/build/commands/traces.d.ts.map +1 -0
- package/build/commands/traces.js +239 -0
- package/build/commands/traces.js.map +1 -0
- package/build/config.d.ts +70 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +77 -0
- package/build/config.js.map +1 -0
- package/{dist/src → build}/index.d.ts.map +1 -1
- package/{dist/esm → build}/index.js +0 -0
- package/build/index.js.map +1 -0
- package/build/io.d.ts +49 -0
- package/build/io.d.ts.map +1 -0
- package/build/io.js +29 -0
- package/build/io.js.map +1 -0
- package/build/trace.d.ts +41 -0
- package/build/trace.d.ts.map +1 -0
- package/build/trace.js +55 -0
- package/build/trace.js.map +1 -0
- package/package.json +19 -15
- package/dist/esm/cli.d.ts.map +0 -1
- package/dist/esm/cli.js +0 -17
- package/dist/esm/cli.js.map +0 -1
- package/dist/esm/commands/index.d.ts +0 -1
- package/dist/esm/commands/index.d.ts.map +0 -1
- package/dist/esm/commands/index.js +0 -8
- package/dist/esm/commands/index.js.map +0 -1
- package/dist/esm/index.d.ts.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/package.json +0 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +0 -1
- package/dist/esm/utils/index.d.ts +0 -1
- package/dist/esm/utils/index.d.ts.map +0 -1
- package/dist/esm/utils/index.js +0 -8
- package/dist/esm/utils/index.js.map +0 -1
- package/dist/src/cli.d.ts +0 -3
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js +0 -20
- package/dist/src/cli.js.map +0 -1
- package/dist/src/commands/index.d.ts +0 -2
- package/dist/src/commands/index.d.ts.map +0 -1
- package/dist/src/commands/index.js +0 -9
- package/dist/src/commands/index.js.map +0 -1
- package/dist/src/index.d.ts +0 -3
- package/dist/src/index.js +0 -8
- package/dist/src/index.js.map +0 -1
- package/dist/src/utils/index.d.ts +0 -2
- package/dist/src/utils/index.d.ts.map +0 -1
- package/dist/src/utils/index.js +0 -9
- package/dist/src/utils/index.js.map +0 -1
- package/dist/test/cli.test.d.ts +0 -2
- package/dist/test/cli.test.d.ts.map +0 -1
- package/dist/test/cli.test.js +0 -12
- package/dist/test/cli.test.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/cli.ts +0 -22
- package/src/commands/index.ts +0 -7
- package/src/index.ts +0 -7
- package/src/utils/index.ts +0 -7
- /package/{dist/esm → build}/cli.d.ts +0 -0
- /package/{dist/esm → build}/index.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,44 +1,307 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center" style="border-bottom: none">
|
|
2
|
+
<div>
|
|
3
|
+
<a href="https://phoenix.arize.com/?utm_medium=github&utm_content=header_img&utm_campaign=phoenix-cli">
|
|
4
|
+
<picture>
|
|
5
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Arize-ai/phoenix-assets/refs/heads/main/logos/Phoenix/phoenix.svg">
|
|
6
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/Arize-ai/phoenix-assets/refs/heads/main/logos/Phoenix/phoenix-white.svg">
|
|
7
|
+
<img alt="Arize Phoenix logo" src="https://raw.githubusercontent.com/Arize-ai/phoenix-assets/refs/heads/main/logos/Phoenix/phoenix.svg" width="100" />
|
|
8
|
+
</picture>
|
|
9
|
+
</a>
|
|
10
|
+
<br>
|
|
11
|
+
@arizeai/phoenix-cli
|
|
12
|
+
</div>
|
|
13
|
+
</h1>
|
|
2
14
|
|
|
3
|
-
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="https://www.npmjs.com/package/@arizeai/phoenix-cli">
|
|
17
|
+
<img src="https://img.shields.io/npm/v/%40arizeai%2Fphoenix-cli" alt="NPM Version">
|
|
18
|
+
</a>
|
|
19
|
+
<a href="https://arize.com/docs/phoenix/">
|
|
20
|
+
<img src="https://img.shields.io/badge/docs-blue?logo=typescript&logoColor=white" alt="Documentation">
|
|
21
|
+
</a>
|
|
22
|
+
<img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=8e8e8b34-7900-43fa-a38f-1f070bd48c64&page=js/packages/phoenix-cli/README.md" />
|
|
23
|
+
</p>
|
|
4
24
|
|
|
5
|
-
|
|
25
|
+
A command-line interface for [Arize Phoenix](https://github.com/Arize-ai/phoenix). Fetch traces, list datasets, and export experiment results directly from your terminal—or pipe them into AI coding agents like Claude Code, Cursor, Codex, and Gemini CLI.
|
|
6
26
|
|
|
7
27
|
## Installation
|
|
8
28
|
|
|
9
29
|
```bash
|
|
10
|
-
# Install globally
|
|
11
30
|
npm install -g @arizeai/phoenix-cli
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or run directly with npx:
|
|
12
34
|
|
|
13
|
-
|
|
35
|
+
```bash
|
|
14
36
|
npx @arizeai/phoenix-cli
|
|
15
37
|
```
|
|
16
38
|
|
|
17
|
-
##
|
|
39
|
+
## Quick Start
|
|
18
40
|
|
|
19
41
|
```bash
|
|
20
|
-
#
|
|
21
|
-
|
|
42
|
+
# Configure your Phoenix instance
|
|
43
|
+
export PHOENIX_HOST=http://localhost:6006
|
|
44
|
+
export PHOENIX_PROJECT=my-project
|
|
45
|
+
export PHOENIX_API_KEY=your-api-key # if authentication is enabled
|
|
22
46
|
|
|
23
|
-
#
|
|
47
|
+
# Fetch the most recent trace
|
|
48
|
+
px traces --limit 1
|
|
49
|
+
|
|
50
|
+
# Fetch a specific trace by ID
|
|
51
|
+
px trace abc123def456
|
|
52
|
+
|
|
53
|
+
# Export traces to a directory
|
|
54
|
+
px traces ./my-traces --limit 50
|
|
24
55
|
```
|
|
25
56
|
|
|
57
|
+
## Environment Variables
|
|
58
|
+
|
|
59
|
+
| Variable | Description |
|
|
60
|
+
| ------------------------ | ---------------------------------------------------- |
|
|
61
|
+
| `PHOENIX_HOST` | Phoenix API endpoint (e.g., `http://localhost:6006`) |
|
|
62
|
+
| `PHOENIX_PROJECT` | Project name or ID |
|
|
63
|
+
| `PHOENIX_API_KEY` | API key for authentication (if required) |
|
|
64
|
+
| `PHOENIX_CLIENT_HEADERS` | Custom headers as JSON string |
|
|
65
|
+
|
|
66
|
+
CLI flags take priority over environment variables.
|
|
67
|
+
|
|
26
68
|
## Commands
|
|
27
69
|
|
|
28
|
-
|
|
70
|
+
### `px projects`
|
|
71
|
+
|
|
72
|
+
List all available projects.
|
|
29
73
|
|
|
30
|
-
|
|
74
|
+
```bash
|
|
75
|
+
px projects
|
|
76
|
+
px projects --format raw # JSON output for piping
|
|
77
|
+
```
|
|
31
78
|
|
|
32
|
-
|
|
79
|
+
### `px traces [directory]`
|
|
33
80
|
|
|
34
|
-
|
|
81
|
+
Fetch recent traces from the configured project.
|
|
35
82
|
|
|
36
83
|
```bash
|
|
37
|
-
|
|
84
|
+
px traces --limit 10 # Output to stdout
|
|
85
|
+
px traces ./my-traces --limit 10 # Save to directory
|
|
86
|
+
px traces --last-n-minutes 60 --limit 20 # Filter by time
|
|
87
|
+
px traces --since 2026-01-13T10:00:00Z # Since timestamp
|
|
88
|
+
px traces --format raw --no-progress | jq # Pipe to jq
|
|
38
89
|
```
|
|
39
90
|
|
|
40
|
-
|
|
91
|
+
| Option | Description | Default |
|
|
92
|
+
| --------------------------- | ----------------------------------------- | -------- |
|
|
93
|
+
| `[directory]` | Save traces as JSON files to directory | stdout |
|
|
94
|
+
| `-n, --limit <number>` | Number of traces to fetch (newest first) | 10 |
|
|
95
|
+
| `--last-n-minutes <number>` | Only fetch traces from the last N minutes | — |
|
|
96
|
+
| `--since <timestamp>` | Fetch traces since ISO timestamp | — |
|
|
97
|
+
| `--format <format>` | `pretty`, `json`, or `raw` | `pretty` |
|
|
98
|
+
| `--no-progress` | Disable progress output | — |
|
|
99
|
+
|
|
100
|
+
### `px trace <trace-id>`
|
|
101
|
+
|
|
102
|
+
Fetch a specific trace by ID.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
px trace abc123def456
|
|
106
|
+
px trace abc123def456 --file trace.json # Save to file
|
|
107
|
+
px trace abc123def456 --format raw | jq # Pipe to jq
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
| Option | Description | Default |
|
|
111
|
+
| ------------------- | ------------------------------ | -------- |
|
|
112
|
+
| `--file <path>` | Save to file instead of stdout | stdout |
|
|
113
|
+
| `--format <format>` | `pretty`, `json`, or `raw` | `pretty` |
|
|
114
|
+
|
|
115
|
+
### `px datasets`
|
|
116
|
+
|
|
117
|
+
List all available datasets.
|
|
41
118
|
|
|
42
119
|
```bash
|
|
43
|
-
|
|
120
|
+
px datasets
|
|
121
|
+
px datasets --format json # JSON output
|
|
122
|
+
px datasets --format raw --no-progress | jq # Pipe to jq
|
|
44
123
|
```
|
|
124
|
+
|
|
125
|
+
| Option | Description | Default |
|
|
126
|
+
| ------------------- | -------------------------- | -------- |
|
|
127
|
+
| `--format <format>` | `pretty`, `json`, or `raw` | `pretty` |
|
|
128
|
+
| `--limit <number>` | Maximum number of datasets | — |
|
|
129
|
+
|
|
130
|
+
### `px dataset <dataset-identifier>`
|
|
131
|
+
|
|
132
|
+
Fetch examples from a dataset.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
px dataset query_response # Fetch all examples
|
|
136
|
+
px dataset query_response --split train # Filter by split
|
|
137
|
+
px dataset query_response --split train --split test # Multiple splits
|
|
138
|
+
px dataset query_response --version <version-id> # Specific version
|
|
139
|
+
px dataset query_response --file dataset.json # Save to file
|
|
140
|
+
px dataset query_response --format raw | jq '.examples[].input'
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
| Option | Description | Default |
|
|
144
|
+
| ---------------- | ---------------------------------------- | -------- |
|
|
145
|
+
| `--split <name>` | Filter by split (can be used repeatedly) | — |
|
|
146
|
+
| `--version <id>` | Fetch from specific dataset version | latest |
|
|
147
|
+
| `--file <path>` | Save to file instead of stdout | stdout |
|
|
148
|
+
| `--format <fmt>` | `pretty`, `json`, or `raw` | `pretty` |
|
|
149
|
+
|
|
150
|
+
### `px experiments --dataset <name-or-id>`
|
|
151
|
+
|
|
152
|
+
List experiments for a dataset, optionally exporting full data to files.
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
px experiments --dataset my-dataset # List experiments
|
|
156
|
+
px experiments --dataset my-dataset --format json # JSON output
|
|
157
|
+
px experiments --dataset my-dataset ./experiments # Export to directory
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
| Option | Description | Default |
|
|
161
|
+
| ------------------------ | ----------------------------------------- | -------- |
|
|
162
|
+
| `--dataset <name-or-id>` | Dataset name or ID (required) | — |
|
|
163
|
+
| `[directory]` | Export experiment JSON files to directory | stdout |
|
|
164
|
+
| `--format <format>` | `pretty`, `json`, or `raw` | `pretty` |
|
|
165
|
+
| `--limit <number>` | Maximum number of experiments | — |
|
|
166
|
+
|
|
167
|
+
### `px experiment <experiment-id>`
|
|
168
|
+
|
|
169
|
+
Fetch a single experiment with all run data.
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
px experiment RXhwZXJpbWVudDox
|
|
173
|
+
px experiment RXhwZXJpbWVudDox --file exp.json # Save to file
|
|
174
|
+
px experiment RXhwZXJpbWVudDox --format json # JSON output
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
| Option | Description | Default |
|
|
178
|
+
| ------------------- | ------------------------------ | -------- |
|
|
179
|
+
| `--file <path>` | Save to file instead of stdout | stdout |
|
|
180
|
+
| `--format <format>` | `pretty`, `json`, or `raw` | `pretty` |
|
|
181
|
+
|
|
182
|
+
## Output Formats
|
|
183
|
+
|
|
184
|
+
**`pretty`** (default) — Human-readable tree view:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
┌─ Trace: abc123def456
|
|
188
|
+
│
|
|
189
|
+
│ Input: What is the weather in San Francisco?
|
|
190
|
+
│ Output: The weather is currently sunny...
|
|
191
|
+
│
|
|
192
|
+
│ Spans:
|
|
193
|
+
│ └─ ✓ agent_run (CHAIN) - 1250ms
|
|
194
|
+
│ ├─ ✓ llm_call (LLM) - 800ms
|
|
195
|
+
│ └─ ✓ tool_execution (TOOL) - 400ms
|
|
196
|
+
└─
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**`json`** — Formatted JSON with indentation.
|
|
200
|
+
|
|
201
|
+
**`raw`** — Compact JSON for piping to `jq` or other tools.
|
|
202
|
+
|
|
203
|
+
## JSON Structure
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"traceId": "abc123def456",
|
|
208
|
+
"spans": [
|
|
209
|
+
{
|
|
210
|
+
"name": "chat_completion",
|
|
211
|
+
"context": {
|
|
212
|
+
"trace_id": "abc123def456",
|
|
213
|
+
"span_id": "span-1"
|
|
214
|
+
},
|
|
215
|
+
"span_kind": "LLM",
|
|
216
|
+
"parent_id": null,
|
|
217
|
+
"start_time": "2026-01-17T10:00:00.000Z",
|
|
218
|
+
"end_time": "2026-01-17T10:00:01.250Z",
|
|
219
|
+
"status_code": "OK",
|
|
220
|
+
"attributes": {
|
|
221
|
+
"llm.model_name": "gpt-4",
|
|
222
|
+
"llm.token_count.prompt": 512,
|
|
223
|
+
"llm.token_count.completion": 256,
|
|
224
|
+
"input.value": "What is the weather?",
|
|
225
|
+
"output.value": "The weather is sunny..."
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
],
|
|
229
|
+
"rootSpan": { ... },
|
|
230
|
+
"startTime": "2026-01-17T10:00:00.000Z",
|
|
231
|
+
"endTime": "2026-01-17T10:00:01.250Z",
|
|
232
|
+
"duration": 1250,
|
|
233
|
+
"status": "OK"
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Spans include [OpenInference](https://github.com/Arize-ai/openinference) semantic attributes like `llm.model_name`, `llm.token_count.*`, `input.value`, `output.value`, `tool.name`, and `exception.*`.
|
|
238
|
+
|
|
239
|
+
## Examples
|
|
240
|
+
|
|
241
|
+
### Debug failed traces
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
px traces --limit 20 --format raw --no-progress | jq '.[] | select(.status == "ERROR")'
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Find slowest traces
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
px traces --limit 10 --format raw --no-progress | jq 'sort_by(-.duration) | .[0:3]'
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Extract LLM models used
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
px traces --limit 50 --format raw --no-progress | \
|
|
257
|
+
jq -r '.[].spans[] | select(.span_kind == "LLM") | .attributes["llm.model_name"]' | sort -u
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Count errors
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
px traces --limit 100 --format raw --no-progress | jq '[.[] | select(.status == "ERROR")] | length'
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### List datasets and experiments
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# List all datasets
|
|
270
|
+
px datasets --format raw --no-progress | jq '.[].name'
|
|
271
|
+
# Output: "query_response"
|
|
272
|
+
|
|
273
|
+
# List experiments for a dataset
|
|
274
|
+
px experiments --dataset query_response --format raw --no-progress | \
|
|
275
|
+
jq '.[] | {id, successful_run_count, failed_run_count}'
|
|
276
|
+
# Output: {"id":"RXhwZXJpbWVudDox","successful_run_count":249,"failed_run_count":1}
|
|
277
|
+
|
|
278
|
+
# Export all experiment data for a dataset to a directory
|
|
279
|
+
px experiments --dataset query_response ./experiments/
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Analyze experiment results
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
# Get input queries and latency from an experiment
|
|
286
|
+
px experiment RXhwZXJpbWVudDox --format raw --no-progress | \
|
|
287
|
+
jq '.[] | {query: .input.query, latency_ms, trace_id}'
|
|
288
|
+
|
|
289
|
+
# Find failed runs in an experiment
|
|
290
|
+
px experiment RXhwZXJpbWVudDox --format raw --no-progress | \
|
|
291
|
+
jq '.[] | select(.error != null) | {query: .input.query, error}'
|
|
292
|
+
# Output: {"query":"looking for complex fodmap meal ideas","error":"peer closed connection..."}
|
|
293
|
+
|
|
294
|
+
# Calculate average latency across runs
|
|
295
|
+
px experiment RXhwZXJpbWVudDox --format raw --no-progress | \
|
|
296
|
+
jq '[.[].latency_ms] | add / length'
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Community
|
|
302
|
+
|
|
303
|
+
- 🌍 [Slack community](https://arize-ai.slack.com/join/shared_invite/zt-11t1vbu4x-xkBIHmOREQnYnYDH1GDfCg)
|
|
304
|
+
- 📚 [Documentation](https://arize.com/docs/phoenix)
|
|
305
|
+
- 🌟 [GitHub](https://github.com/Arize-ai/phoenix)
|
|
306
|
+
- 🐞 [Report bugs](https://github.com/Arize-ai/phoenix/issues)
|
|
307
|
+
- 𝕏 [@ArizePhoenix](https://twitter.com/ArizePhoenix)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAeA,wBAAgB,IAAI,SAuBnB"}
|
package/build/cli.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createDatasetCommand, createDatasetsCommand, createExperimentCommand, createExperimentsCommand, createProjectsCommand, createTraceCommand, createTracesCommand, } from "./commands/index.js";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
// Phoenix CLI Main Logic
|
|
5
|
+
export function main() {
|
|
6
|
+
const program = new Command();
|
|
7
|
+
program
|
|
8
|
+
.name("px")
|
|
9
|
+
.description("Phoenix CLI - AI observability from the command line")
|
|
10
|
+
.version("0.0.4");
|
|
11
|
+
// Register commands
|
|
12
|
+
program.addCommand(createProjectsCommand());
|
|
13
|
+
program.addCommand(createTracesCommand());
|
|
14
|
+
program.addCommand(createTraceCommand());
|
|
15
|
+
program.addCommand(createDatasetsCommand());
|
|
16
|
+
program.addCommand(createDatasetCommand());
|
|
17
|
+
program.addCommand(createExperimentsCommand());
|
|
18
|
+
program.addCommand(createExperimentCommand());
|
|
19
|
+
// Show help if no command provided
|
|
20
|
+
if (process.argv.length === 2) {
|
|
21
|
+
program.help();
|
|
22
|
+
}
|
|
23
|
+
program.parse();
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=cli.js.map
|
package/build/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,yBAAyB;AACzB,MAAM,UAAU,IAAI;IAClB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,IAAI,CAAC;SACV,WAAW,CAAC,sDAAsD,CAAC;SACnE,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,oBAAoB;IACpB,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,UAAU,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,UAAU,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAE9C,mCAAmC;IACnC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,IAAI,EAAE,CAAC;IACjB,CAAC;IAED,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type PhoenixClient } from "@arizeai/phoenix-client";
|
|
2
|
+
import type { PhoenixConfig } from "./config.js";
|
|
3
|
+
export interface CreatePhoenixClientOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Resolved Phoenix CLI configuration.
|
|
6
|
+
*/
|
|
7
|
+
config: PhoenixConfig;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create a Phoenix client from configuration
|
|
11
|
+
*/
|
|
12
|
+
export declare function createPhoenixClient({ config, }: CreatePhoenixClientOptions): PhoenixClient;
|
|
13
|
+
export interface ResolveProjectIdOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Phoenix API client.
|
|
16
|
+
*/
|
|
17
|
+
client: PhoenixClient;
|
|
18
|
+
/**
|
|
19
|
+
* Project identifier to resolve.
|
|
20
|
+
*
|
|
21
|
+
* Phoenix project IDs are hex-encoded strings. If `projectIdentifier` looks like a hex string,
|
|
22
|
+
* it's treated as an ID; otherwise it's treated as a name and resolved via the API.
|
|
23
|
+
*/
|
|
24
|
+
projectIdentifier: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve project identifier to project ID
|
|
28
|
+
* If the identifier looks like a Phoenix project ID (hex string), returns it as-is; otherwise fetches by name.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveProjectId({ client, projectIdentifier, }: ResolveProjectIdOptions): Promise<string>;
|
|
31
|
+
export interface ResolveDatasetIdOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Phoenix API client.
|
|
34
|
+
*/
|
|
35
|
+
client: PhoenixClient;
|
|
36
|
+
/**
|
|
37
|
+
* Dataset identifier to resolve.
|
|
38
|
+
*
|
|
39
|
+
* Phoenix dataset IDs are hex-encoded strings. If `datasetIdentifier` looks like a hex string,
|
|
40
|
+
* it's treated as an ID; otherwise it's treated as a name and resolved via the API.
|
|
41
|
+
*/
|
|
42
|
+
datasetIdentifier: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Resolve dataset identifier to dataset ID
|
|
46
|
+
* If the identifier looks like a Phoenix dataset ID (hex string), returns it as-is; otherwise fetches by name.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveDatasetId({ client, datasetIdentifier, }: ResolveDatasetIdOptions): Promise<string>;
|
|
49
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,MAAM,EAAE,aAAa,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,GACP,EAAE,0BAA0B,GAAG,aAAa,CAqB5C;AAED,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,MAAM,EAAE,aAAa,CAAC;IACtB;;;;;OAKG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAWD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,MAAM,EACN,iBAAiB,GAClB,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2B3C;AAED,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,MAAM,EAAE,aAAa,CAAC;IACtB;;;;;OAKG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAWD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,MAAM,EACN,iBAAiB,GAClB,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiC3C"}
|
package/build/client.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { createClient } from "@arizeai/phoenix-client";
|
|
2
|
+
/**
|
|
3
|
+
* Create a Phoenix client from configuration
|
|
4
|
+
*/
|
|
5
|
+
export function createPhoenixClient({ config, }) {
|
|
6
|
+
const baseUrl = config.endpoint;
|
|
7
|
+
if (!baseUrl) {
|
|
8
|
+
throw new Error("Phoenix endpoint not configured");
|
|
9
|
+
}
|
|
10
|
+
const headers = {
|
|
11
|
+
...(config.headers || {}),
|
|
12
|
+
};
|
|
13
|
+
if (config.apiKey) {
|
|
14
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
15
|
+
}
|
|
16
|
+
return createClient({
|
|
17
|
+
options: {
|
|
18
|
+
baseUrl,
|
|
19
|
+
headers,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function looksLikePhoenixProjectId(projectIdentifier) {
|
|
24
|
+
// Project IDs are hex-encoded strings (e.g., "a1b2c3d4e5f6...")
|
|
25
|
+
const trimmed = projectIdentifier.trim();
|
|
26
|
+
if (!trimmed)
|
|
27
|
+
return false;
|
|
28
|
+
// Check if the string is a valid hex string (only 0-9, a-f, A-F)
|
|
29
|
+
return /^[0-9a-fA-F]+$/.test(trimmed);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve project identifier to project ID
|
|
33
|
+
* If the identifier looks like a Phoenix project ID (hex string), returns it as-is; otherwise fetches by name.
|
|
34
|
+
*/
|
|
35
|
+
export async function resolveProjectId({ client, projectIdentifier, }) {
|
|
36
|
+
if (looksLikePhoenixProjectId(projectIdentifier)) {
|
|
37
|
+
return projectIdentifier;
|
|
38
|
+
}
|
|
39
|
+
// Otherwise, fetch the project by name to get its ID
|
|
40
|
+
try {
|
|
41
|
+
const response = await client.GET("/v1/projects/{project_identifier}", {
|
|
42
|
+
params: {
|
|
43
|
+
path: {
|
|
44
|
+
project_identifier: projectIdentifier,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
if (response.error || !response.data) {
|
|
49
|
+
throw new Error(`Failed to resolve project "${projectIdentifier}": ${response.error}`);
|
|
50
|
+
}
|
|
51
|
+
return response.data.data.id;
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
throw new Error(`Failed to resolve project "${projectIdentifier}": ${error instanceof Error ? error.message : String(error)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function looksLikePhoenixDatasetId(datasetIdentifier) {
|
|
58
|
+
// Dataset IDs are hex-encoded strings (e.g., "a1b2c3d4e5f6...")
|
|
59
|
+
const trimmed = datasetIdentifier.trim();
|
|
60
|
+
if (!trimmed)
|
|
61
|
+
return false;
|
|
62
|
+
// Check if the string is a valid hex string (only 0-9, a-f, A-F)
|
|
63
|
+
return /^[0-9a-fA-F]+$/.test(trimmed);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Resolve dataset identifier to dataset ID
|
|
67
|
+
* If the identifier looks like a Phoenix dataset ID (hex string), returns it as-is; otherwise fetches by name.
|
|
68
|
+
*/
|
|
69
|
+
export async function resolveDatasetId({ client, datasetIdentifier, }) {
|
|
70
|
+
if (looksLikePhoenixDatasetId(datasetIdentifier)) {
|
|
71
|
+
return datasetIdentifier;
|
|
72
|
+
}
|
|
73
|
+
// Otherwise, fetch the dataset by name to get its ID
|
|
74
|
+
try {
|
|
75
|
+
const response = await client.GET("/v1/datasets", {
|
|
76
|
+
params: {
|
|
77
|
+
query: {
|
|
78
|
+
name: datasetIdentifier,
|
|
79
|
+
limit: 1,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
if (response.error || !response.data) {
|
|
84
|
+
throw new Error(`Failed to resolve dataset "${datasetIdentifier}": ${response.error}`);
|
|
85
|
+
}
|
|
86
|
+
const datasets = response.data.data;
|
|
87
|
+
if (datasets.length === 0) {
|
|
88
|
+
throw new Error(`Dataset not found: "${datasetIdentifier}"`);
|
|
89
|
+
}
|
|
90
|
+
return datasets[0].id;
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
throw new Error(`Failed to resolve dataset "${datasetIdentifier}": ${error instanceof Error ? error.message : String(error)}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../../src/commands/dataset.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6KpC;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAyB9C"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { createPhoenixClient, resolveDatasetId } from "../client.js";
|
|
2
|
+
import { getConfigErrorMessage, resolveConfig } from "../config.js";
|
|
3
|
+
import { writeError, writeOutput, writeProgress } from "../io.js";
|
|
4
|
+
import { formatDatasetExamplesOutput, } from "./formatDataset.js";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
/**
|
|
8
|
+
* Fetch dataset examples from Phoenix
|
|
9
|
+
*/
|
|
10
|
+
async function fetchDatasetExamples(client, datasetId, options = {}) {
|
|
11
|
+
const response = await client.GET("/v1/datasets/{id}/examples", {
|
|
12
|
+
params: {
|
|
13
|
+
path: {
|
|
14
|
+
id: datasetId,
|
|
15
|
+
},
|
|
16
|
+
query: {
|
|
17
|
+
version_id: options.versionId,
|
|
18
|
+
split: options.splits,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (response.error || !response.data) {
|
|
23
|
+
throw new Error(`Failed to fetch dataset examples: ${response.error}`);
|
|
24
|
+
}
|
|
25
|
+
return response.data.data;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fetch dataset metadata for display name
|
|
29
|
+
*/
|
|
30
|
+
async function fetchDatasetName(client, datasetId) {
|
|
31
|
+
try {
|
|
32
|
+
const response = await client.GET("/v1/datasets/{id}", {
|
|
33
|
+
params: {
|
|
34
|
+
path: {
|
|
35
|
+
id: datasetId,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
if (response.error || !response.data) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
return response.data.data.name;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Dataset command handler
|
|
50
|
+
*/
|
|
51
|
+
async function datasetHandler(datasetIdentifier, options) {
|
|
52
|
+
try {
|
|
53
|
+
const userSpecifiedFormat = process.argv.includes("--format") ||
|
|
54
|
+
process.argv.some((arg) => arg.startsWith("--format="));
|
|
55
|
+
// Resolve configuration
|
|
56
|
+
const config = resolveConfig({
|
|
57
|
+
cliOptions: {
|
|
58
|
+
endpoint: options.endpoint,
|
|
59
|
+
apiKey: options.apiKey,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
// Validate that we have endpoint
|
|
63
|
+
if (!config.endpoint) {
|
|
64
|
+
const errors = [
|
|
65
|
+
"Phoenix endpoint not configured. Set PHOENIX_HOST environment variable or use --endpoint flag.",
|
|
66
|
+
];
|
|
67
|
+
writeError({ message: getConfigErrorMessage({ errors }) });
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
// Create client
|
|
71
|
+
const client = createPhoenixClient({ config });
|
|
72
|
+
writeProgress({
|
|
73
|
+
message: `Resolving dataset: ${datasetIdentifier}`,
|
|
74
|
+
noProgress: !options.progress,
|
|
75
|
+
});
|
|
76
|
+
// Resolve dataset ID
|
|
77
|
+
const datasetId = await resolveDatasetId({
|
|
78
|
+
client,
|
|
79
|
+
datasetIdentifier,
|
|
80
|
+
});
|
|
81
|
+
// Fetch dataset name for display
|
|
82
|
+
const datasetName = await fetchDatasetName(client, datasetId);
|
|
83
|
+
writeProgress({
|
|
84
|
+
message: `Fetching examples from dataset ${datasetName || datasetId}...`,
|
|
85
|
+
noProgress: !options.progress,
|
|
86
|
+
});
|
|
87
|
+
// Fetch dataset examples
|
|
88
|
+
const data = await fetchDatasetExamples(client, datasetId, {
|
|
89
|
+
versionId: options.version,
|
|
90
|
+
splits: options.split,
|
|
91
|
+
});
|
|
92
|
+
writeProgress({
|
|
93
|
+
message: `Found ${data.examples.length} example(s)`,
|
|
94
|
+
noProgress: !options.progress,
|
|
95
|
+
});
|
|
96
|
+
// Determine output format
|
|
97
|
+
const outputFormat = options.file
|
|
98
|
+
? "json"
|
|
99
|
+
: options.format || "pretty";
|
|
100
|
+
if (options.file && userSpecifiedFormat && options.format !== "json") {
|
|
101
|
+
writeError({
|
|
102
|
+
message: `Warning: --format is ignored when writing to a file; writing JSON to ${options.file}`,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// Format output
|
|
106
|
+
const output = formatDatasetExamplesOutput({
|
|
107
|
+
data,
|
|
108
|
+
datasetName,
|
|
109
|
+
format: outputFormat,
|
|
110
|
+
});
|
|
111
|
+
if (options.file) {
|
|
112
|
+
fs.writeFileSync(options.file, output, "utf-8");
|
|
113
|
+
writeProgress({
|
|
114
|
+
message: `Wrote dataset to ${options.file}`,
|
|
115
|
+
noProgress: !options.progress,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
writeOutput({ message: output });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
writeError({
|
|
124
|
+
message: `Error fetching dataset: ${error instanceof Error ? error.message : String(error)}`,
|
|
125
|
+
});
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Collect multiple --split options into an array
|
|
131
|
+
*/
|
|
132
|
+
function collectSplits(value, previous) {
|
|
133
|
+
return previous.concat([value]);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create the dataset command
|
|
137
|
+
*/
|
|
138
|
+
export function createDatasetCommand() {
|
|
139
|
+
const command = new Command("dataset");
|
|
140
|
+
command
|
|
141
|
+
.description("Fetch examples from a dataset")
|
|
142
|
+
.argument("<dataset-identifier>", "Dataset name or ID")
|
|
143
|
+
.option("--endpoint <url>", "Phoenix API endpoint")
|
|
144
|
+
.option("--api-key <key>", "Phoenix API key for authentication")
|
|
145
|
+
.option("--format <format>", "Output format: pretty, json, or raw", "pretty")
|
|
146
|
+
.option("--no-progress", "Disable progress indicators")
|
|
147
|
+
.option("--file <path>", "Save output to file instead of stdout")
|
|
148
|
+
.option("--split <name>", "Filter by split name (can be used multiple times)", collectSplits, [])
|
|
149
|
+
.option("--version <id>", "Fetch from a specific dataset version")
|
|
150
|
+
.action(datasetHandler);
|
|
151
|
+
return command;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=dataset.js.map
|