@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.
Files changed (121) hide show
  1. package/README.md +279 -16
  2. package/build/cli.d.ts.map +1 -0
  3. package/build/cli.js +25 -0
  4. package/build/cli.js.map +1 -0
  5. package/build/client.d.ts +49 -0
  6. package/build/client.d.ts.map +1 -0
  7. package/build/client.js +96 -0
  8. package/build/client.js.map +1 -0
  9. package/build/commands/dataset.d.ts +6 -0
  10. package/build/commands/dataset.d.ts.map +1 -0
  11. package/build/commands/dataset.js +153 -0
  12. package/build/commands/dataset.js.map +1 -0
  13. package/build/commands/datasets.d.ts +6 -0
  14. package/build/commands/datasets.d.ts.map +1 -0
  15. package/build/commands/datasets.js +97 -0
  16. package/build/commands/datasets.js.map +1 -0
  17. package/build/commands/experiment.d.ts +6 -0
  18. package/build/commands/experiment.d.ts.map +1 -0
  19. package/build/commands/experiment.js +106 -0
  20. package/build/commands/experiment.js.map +1 -0
  21. package/build/commands/experiments.d.ts +6 -0
  22. package/build/commands/experiments.d.ts.map +1 -0
  23. package/build/commands/experiments.js +201 -0
  24. package/build/commands/experiments.js.map +1 -0
  25. package/build/commands/formatDataset.d.ts +26 -0
  26. package/build/commands/formatDataset.d.ts.map +1 -0
  27. package/build/commands/formatDataset.js +60 -0
  28. package/build/commands/formatDataset.js.map +1 -0
  29. package/build/commands/formatDatasets.d.ts +27 -0
  30. package/build/commands/formatDatasets.d.ts.map +1 -0
  31. package/build/commands/formatDatasets.js +76 -0
  32. package/build/commands/formatDatasets.js.map +1 -0
  33. package/build/commands/formatExperiment.d.ts +35 -0
  34. package/build/commands/formatExperiment.d.ts.map +1 -0
  35. package/build/commands/formatExperiment.js +191 -0
  36. package/build/commands/formatExperiment.js.map +1 -0
  37. package/build/commands/formatExperiments.d.ts +16 -0
  38. package/build/commands/formatExperiments.d.ts.map +1 -0
  39. package/build/commands/formatExperiments.js +53 -0
  40. package/build/commands/formatExperiments.js.map +1 -0
  41. package/build/commands/formatProjects.d.ts +19 -0
  42. package/build/commands/formatProjects.d.ts.map +1 -0
  43. package/build/commands/formatProjects.js +21 -0
  44. package/build/commands/formatProjects.js.map +1 -0
  45. package/build/commands/formatTraces.d.ts +25 -0
  46. package/build/commands/formatTraces.d.ts.map +1 -0
  47. package/build/commands/formatTraces.js +165 -0
  48. package/build/commands/formatTraces.js.map +1 -0
  49. package/build/commands/index.d.ts +8 -0
  50. package/build/commands/index.d.ts.map +1 -0
  51. package/build/commands/index.js +8 -0
  52. package/build/commands/index.js.map +1 -0
  53. package/build/commands/projects.d.ts +6 -0
  54. package/build/commands/projects.d.ts.map +1 -0
  55. package/build/commands/projects.js +87 -0
  56. package/build/commands/projects.js.map +1 -0
  57. package/build/commands/trace.d.ts +6 -0
  58. package/build/commands/trace.d.ts.map +1 -0
  59. package/build/commands/trace.js +143 -0
  60. package/build/commands/trace.js.map +1 -0
  61. package/build/commands/traces.d.ts +6 -0
  62. package/build/commands/traces.d.ts.map +1 -0
  63. package/build/commands/traces.js +239 -0
  64. package/build/commands/traces.js.map +1 -0
  65. package/build/config.d.ts +70 -0
  66. package/build/config.d.ts.map +1 -0
  67. package/build/config.js +77 -0
  68. package/build/config.js.map +1 -0
  69. package/{dist/src → build}/index.d.ts.map +1 -1
  70. package/{dist/esm → build}/index.js +0 -0
  71. package/build/index.js.map +1 -0
  72. package/build/io.d.ts +49 -0
  73. package/build/io.d.ts.map +1 -0
  74. package/build/io.js +29 -0
  75. package/build/io.js.map +1 -0
  76. package/build/trace.d.ts +41 -0
  77. package/build/trace.d.ts.map +1 -0
  78. package/build/trace.js +55 -0
  79. package/build/trace.js.map +1 -0
  80. package/package.json +19 -15
  81. package/dist/esm/cli.d.ts.map +0 -1
  82. package/dist/esm/cli.js +0 -17
  83. package/dist/esm/cli.js.map +0 -1
  84. package/dist/esm/commands/index.d.ts +0 -1
  85. package/dist/esm/commands/index.d.ts.map +0 -1
  86. package/dist/esm/commands/index.js +0 -8
  87. package/dist/esm/commands/index.js.map +0 -1
  88. package/dist/esm/index.d.ts.map +0 -1
  89. package/dist/esm/index.js.map +0 -1
  90. package/dist/esm/package.json +0 -1
  91. package/dist/esm/tsconfig.esm.tsbuildinfo +0 -1
  92. package/dist/esm/utils/index.d.ts +0 -1
  93. package/dist/esm/utils/index.d.ts.map +0 -1
  94. package/dist/esm/utils/index.js +0 -8
  95. package/dist/esm/utils/index.js.map +0 -1
  96. package/dist/src/cli.d.ts +0 -3
  97. package/dist/src/cli.d.ts.map +0 -1
  98. package/dist/src/cli.js +0 -20
  99. package/dist/src/cli.js.map +0 -1
  100. package/dist/src/commands/index.d.ts +0 -2
  101. package/dist/src/commands/index.d.ts.map +0 -1
  102. package/dist/src/commands/index.js +0 -9
  103. package/dist/src/commands/index.js.map +0 -1
  104. package/dist/src/index.d.ts +0 -3
  105. package/dist/src/index.js +0 -8
  106. package/dist/src/index.js.map +0 -1
  107. package/dist/src/utils/index.d.ts +0 -2
  108. package/dist/src/utils/index.d.ts.map +0 -1
  109. package/dist/src/utils/index.js +0 -9
  110. package/dist/src/utils/index.js.map +0 -1
  111. package/dist/test/cli.test.d.ts +0 -2
  112. package/dist/test/cli.test.d.ts.map +0 -1
  113. package/dist/test/cli.test.js +0 -12
  114. package/dist/test/cli.test.js.map +0 -1
  115. package/dist/tsconfig.tsbuildinfo +0 -1
  116. package/src/cli.ts +0 -22
  117. package/src/commands/index.ts +0 -7
  118. package/src/index.ts +0 -7
  119. package/src/utils/index.ts +0 -7
  120. /package/{dist/esm → build}/cli.d.ts +0 -0
  121. /package/{dist/esm → build}/index.d.ts +0 -0
package/README.md CHANGED
@@ -1,44 +1,307 @@
1
- # @arizeai/phoenix-cli
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
- A command-line interface for [Arize Phoenix](https://github.com/Arize-ai/phoenix).
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
- > **Note:** This package is currently under development and not yet ready for use.
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
- # Or use with npx
35
+ ```bash
14
36
  npx @arizeai/phoenix-cli
15
37
  ```
16
38
 
17
- ## Usage
39
+ ## Quick Start
18
40
 
19
41
  ```bash
20
- # View help
21
- phoenix-cli --help
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
- # TODO: Add usage examples here
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
- > **Coming Soon:** Commands will be added to interact with Phoenix prompts, datasets, experiments, and more.
70
+ ### `px projects`
71
+
72
+ List all available projects.
29
73
 
30
- ## Development
74
+ ```bash
75
+ px projects
76
+ px projects --format raw # JSON output for piping
77
+ ```
31
78
 
32
- This package is part of the Phoenix monorepo and uses the existing `@arizeai/phoenix-client` library.
79
+ ### `px traces [directory]`
33
80
 
34
- ### Building
81
+ Fetch recent traces from the configured project.
35
82
 
36
83
  ```bash
37
- pnpm build
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
- ### Testing
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
- pnpm test
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
@@ -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"}
@@ -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,6 @@
1
+ import { Command } from "commander";
2
+ /**
3
+ * Create the dataset command
4
+ */
5
+ export declare function createDatasetCommand(): Command;
6
+ //# sourceMappingURL=dataset.d.ts.map
@@ -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