@arizeai/phoenix-client 7.6.0 → 7.7.1
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/CHANGELOG.md +18 -0
- package/README.md +27 -3
- package/dist/esm/__generated__/api/v1.d.ts +1 -1
- package/dist/esm/__generated__/api/v1.d.ts.map +1 -1
- package/dist/esm/constants/serverRequirements.d.ts +1 -0
- package/dist/esm/constants/serverRequirements.d.ts.map +1 -1
- package/dist/esm/constants/serverRequirements.js +7 -0
- package/dist/esm/constants/serverRequirements.js.map +1 -1
- package/dist/esm/experiments/resumeEvaluation.d.ts +0 -60
- package/dist/esm/experiments/resumeEvaluation.d.ts.map +1 -1
- package/dist/esm/experiments/resumeEvaluation.js +44 -37
- package/dist/esm/experiments/resumeEvaluation.js.map +1 -1
- package/dist/esm/experiments/resumeExperiment.d.ts +0 -52
- package/dist/esm/experiments/resumeExperiment.d.ts.map +1 -1
- package/dist/esm/experiments/resumeExperiment.js +42 -35
- package/dist/esm/experiments/resumeExperiment.js.map +1 -1
- package/dist/esm/experiments/runExperiment.d.ts.map +1 -1
- package/dist/esm/experiments/runExperiment.js +152 -123
- package/dist/esm/experiments/runExperiment.js.map +1 -1
- package/dist/esm/projects/index.d.ts +1 -0
- package/dist/esm/projects/index.d.ts.map +1 -1
- package/dist/esm/projects/index.js +1 -0
- package/dist/esm/projects/index.js.map +1 -1
- package/dist/esm/projects/setProjectRetentionPolicy.d.ts +49 -0
- package/dist/esm/projects/setProjectRetentionPolicy.d.ts.map +1 -0
- package/dist/esm/projects/setProjectRetentionPolicy.js +52 -0
- package/dist/esm/projects/setProjectRetentionPolicy.js.map +1 -0
- package/dist/esm/prompts/sdks/toOpenAI.d.ts.map +1 -1
- package/dist/esm/prompts/sdks/toOpenAI.js +49 -58
- package/dist/esm/prompts/sdks/toOpenAI.js.map +1 -1
- package/dist/esm/sessions/sessionUtils.d.ts.map +1 -1
- package/dist/esm/sessions/sessionUtils.js +3 -0
- package/dist/esm/sessions/sessionUtils.js.map +1 -1
- package/dist/esm/spans/getSpans.d.ts +0 -70
- package/dist/esm/spans/getSpans.d.ts.map +1 -1
- package/dist/esm/spans/getSpans.js +42 -93
- package/dist/esm/spans/getSpans.js.map +1 -1
- package/dist/esm/testing/phoenix-test-tracking.d.ts.map +1 -1
- package/dist/esm/testing/phoenix-test-tracking.js +109 -78
- package/dist/esm/testing/phoenix-test-tracking.js.map +1 -1
- package/dist/esm/traces/getTraces.d.ts +1 -1
- package/dist/esm/traces/getTraces.d.ts.map +1 -1
- package/dist/esm/traces/index.d.ts +1 -0
- package/dist/esm/traces/index.d.ts.map +1 -1
- package/dist/esm/traces/index.js +1 -0
- package/dist/esm/traces/index.js.map +1 -1
- package/dist/esm/traces/transferTraces.d.ts +56 -0
- package/dist/esm/traces/transferTraces.d.ts.map +1 -0
- package/dist/esm/traces/transferTraces.js +56 -0
- package/dist/esm/traces/transferTraces.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types/sessions.d.ts +6 -0
- package/dist/esm/types/sessions.d.ts.map +1 -1
- package/dist/esm/users/getCurrentUser.d.ts +25 -0
- package/dist/esm/users/getCurrentUser.d.ts.map +1 -0
- package/dist/esm/users/getCurrentUser.js +30 -0
- package/dist/esm/users/getCurrentUser.js.map +1 -0
- package/dist/esm/users/index.d.ts +2 -0
- package/dist/esm/users/index.d.ts.map +1 -0
- package/dist/esm/users/index.js +2 -0
- package/dist/esm/users/index.js.map +1 -0
- package/dist/src/__generated__/api/v1.d.ts +1 -1
- package/dist/src/__generated__/api/v1.d.ts.map +1 -1
- package/dist/src/constants/serverRequirements.d.ts +1 -0
- package/dist/src/constants/serverRequirements.d.ts.map +1 -1
- package/dist/src/constants/serverRequirements.js +8 -1
- package/dist/src/constants/serverRequirements.js.map +1 -1
- package/dist/src/experiments/resumeEvaluation.d.ts +0 -60
- package/dist/src/experiments/resumeEvaluation.d.ts.map +1 -1
- package/dist/src/experiments/resumeEvaluation.js +44 -37
- package/dist/src/experiments/resumeEvaluation.js.map +1 -1
- package/dist/src/experiments/resumeExperiment.d.ts +0 -52
- package/dist/src/experiments/resumeExperiment.d.ts.map +1 -1
- package/dist/src/experiments/resumeExperiment.js +42 -35
- package/dist/src/experiments/resumeExperiment.js.map +1 -1
- package/dist/src/experiments/runExperiment.d.ts.map +1 -1
- package/dist/src/experiments/runExperiment.js +148 -116
- package/dist/src/experiments/runExperiment.js.map +1 -1
- package/dist/src/projects/index.d.ts +1 -0
- package/dist/src/projects/index.d.ts.map +1 -1
- package/dist/src/projects/index.js +1 -0
- package/dist/src/projects/index.js.map +1 -1
- package/dist/src/projects/setProjectRetentionPolicy.d.ts +49 -0
- package/dist/src/projects/setProjectRetentionPolicy.d.ts.map +1 -0
- package/dist/src/projects/setProjectRetentionPolicy.js +59 -0
- package/dist/src/projects/setProjectRetentionPolicy.js.map +1 -0
- package/dist/src/prompts/sdks/toOpenAI.d.ts.map +1 -1
- package/dist/src/prompts/sdks/toOpenAI.js +56 -63
- package/dist/src/prompts/sdks/toOpenAI.js.map +1 -1
- package/dist/src/sessions/sessionUtils.d.ts.map +1 -1
- package/dist/src/sessions/sessionUtils.js +3 -0
- package/dist/src/sessions/sessionUtils.js.map +1 -1
- package/dist/src/spans/getSpans.d.ts +0 -70
- package/dist/src/spans/getSpans.d.ts.map +1 -1
- package/dist/src/spans/getSpans.js +43 -94
- package/dist/src/spans/getSpans.js.map +1 -1
- package/dist/src/testing/phoenix-test-tracking.d.ts.map +1 -1
- package/dist/src/testing/phoenix-test-tracking.js +117 -84
- package/dist/src/testing/phoenix-test-tracking.js.map +1 -1
- package/dist/src/traces/getTraces.d.ts +1 -1
- package/dist/src/traces/getTraces.d.ts.map +1 -1
- package/dist/src/traces/index.d.ts +1 -0
- package/dist/src/traces/index.d.ts.map +1 -1
- package/dist/src/traces/index.js +1 -0
- package/dist/src/traces/index.js.map +1 -1
- package/dist/src/traces/transferTraces.d.ts +56 -0
- package/dist/src/traces/transferTraces.d.ts.map +1 -0
- package/dist/src/traces/transferTraces.js +59 -0
- package/dist/src/traces/transferTraces.js.map +1 -0
- package/dist/src/types/sessions.d.ts +6 -0
- package/dist/src/types/sessions.d.ts.map +1 -1
- package/dist/src/users/getCurrentUser.d.ts +25 -0
- package/dist/src/users/getCurrentUser.d.ts.map +1 -0
- package/dist/src/users/getCurrentUser.js +36 -0
- package/dist/src/users/getCurrentUser.js.map +1 -0
- package/dist/src/users/index.d.ts +2 -0
- package/dist/src/users/index.d.ts.map +1 -0
- package/dist/src/users/index.js +18 -0
- package/dist/src/users/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/overview.mdx +8 -4
- package/docs/projects.mdx +71 -0
- package/docs/sessions.mdx +10 -1
- package/docs/traces.mdx +28 -2
- package/docs/users.mdx +44 -0
- package/package.json +6 -2
- package/src/__generated__/api/v1.ts +1 -1
- package/src/constants/serverRequirements.ts +8 -0
- package/src/experiments/resumeEvaluation.ts +78 -48
- package/src/experiments/resumeExperiment.ts +73 -46
- package/src/experiments/runExperiment.ts +235 -129
- package/src/projects/index.ts +1 -0
- package/src/projects/setProjectRetentionPolicy.ts +80 -0
- package/src/prompts/sdks/toOpenAI.ts +58 -61
- package/src/sessions/sessionUtils.ts +3 -0
- package/src/spans/getSpans.ts +84 -48
- package/src/testing/phoenix-test-tracking.ts +154 -90
- package/src/traces/getTraces.ts +1 -1
- package/src/traces/index.ts +1 -0
- package/src/traces/transferTraces.ts +89 -0
- package/src/types/sessions.ts +6 -0
- package/src/users/getCurrentUser.ts +39 -0
- package/src/users/index.ts +1 -0
package/docs/overview.mdx
CHANGED
|
@@ -3,7 +3,7 @@ title: "Overview"
|
|
|
3
3
|
description: "Typed TypeScript client for Phoenix platform APIs"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
`@arizeai/phoenix-client` is the typed TypeScript client for Phoenix platform APIs. It ships a small root REST client plus focused module entrypoints for prompts, datasets, experiments, spans, sessions, traces, and CI-friendly dataset-backed eval tests.
|
|
6
|
+
`@arizeai/phoenix-client` is the typed TypeScript client for Phoenix platform APIs. It ships a small root REST client plus focused module entrypoints for projects, prompts, datasets, experiments, spans, sessions, traces, users, and CI-friendly dataset-backed eval tests.
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
@@ -37,12 +37,14 @@ That gives the agent version-matched docs plus the exact implementation and gene
|
|
|
37
37
|
| Import | Purpose |
|
|
38
38
|
|--------|---------|
|
|
39
39
|
| `@arizeai/phoenix-client` | `createClient`, generated OpenAPI types, config helpers |
|
|
40
|
+
| `@arizeai/phoenix-client/projects` | Project listing and retention-policy assignment |
|
|
40
41
|
| `@arizeai/phoenix-client/prompts` | Prompt CRUD plus `toSDK` conversion |
|
|
41
42
|
| `@arizeai/phoenix-client/datasets` | Dataset creation and retrieval |
|
|
42
43
|
| `@arizeai/phoenix-client/experiments` | Experiment execution and lifecycle |
|
|
43
44
|
| `@arizeai/phoenix-client/spans` | Span search, notes, and span/document annotations |
|
|
44
45
|
| `@arizeai/phoenix-client/sessions` | Session listing, retrieval, and session annotations |
|
|
45
|
-
| `@arizeai/phoenix-client/traces` | Project trace retrieval and trace annotations |
|
|
46
|
+
| `@arizeai/phoenix-client/traces` | Project trace retrieval, transfers, and trace annotations |
|
|
47
|
+
| `@arizeai/phoenix-client/users` | Current authenticated user retrieval |
|
|
46
48
|
| `@arizeai/phoenix-client/vitest` | Vitest entrypoint for dataset-backed eval tests |
|
|
47
49
|
| `@arizeai/phoenix-client/vitest/reporter` | Vitest reporter for Phoenix eval summaries |
|
|
48
50
|
| `@arizeai/phoenix-client/jest` | Jest entrypoint for dataset-backed eval tests |
|
|
@@ -158,10 +160,10 @@ Prefer this layer when:
|
|
|
158
160
|
|
|
159
161
|
## Where To Start
|
|
160
162
|
|
|
161
|
-
- [Prompts](./prompts), [Datasets](./datasets), [Experiments](./experiments) — higher-level workflows
|
|
163
|
+
- [Projects](./projects), [Prompts](./prompts), [Datasets](./datasets), [Experiments](./experiments) — higher-level workflows
|
|
162
164
|
- [Annotations](./annotations) — annotation concepts, then [Span](./span-annotations), [Document](./document-annotations), and [Session](./session-annotations) annotations for detailed usage
|
|
163
165
|
- [CI Eval Tests](./ci-evals) — Vitest/Jest eval suites backed by Phoenix datasets and experiments
|
|
164
|
-
- [Spans](./spans), [Sessions](./sessions), [Traces](./traces) — retrieval and maintenance
|
|
166
|
+
- [Spans](./spans), [Sessions](./sessions), [Traces](./traces), [Users](./users) — retrieval and maintenance
|
|
165
167
|
|
|
166
168
|
<section className="hidden" data-agent-context="source-map" aria-label="Source map">
|
|
167
169
|
<h2>Source Map</h2>
|
|
@@ -171,12 +173,14 @@ Prefer this layer when:
|
|
|
171
173
|
<li><code>src/config.ts</code></li>
|
|
172
174
|
<li><code>src/__generated__/api/v1.ts</code></li>
|
|
173
175
|
<li><code>src/types/core.ts</code></li>
|
|
176
|
+
<li><code>src/projects/</code></li>
|
|
174
177
|
<li><code>src/prompts/</code></li>
|
|
175
178
|
<li><code>src/datasets/</code></li>
|
|
176
179
|
<li><code>src/experiments/</code></li>
|
|
177
180
|
<li><code>src/spans/</code></li>
|
|
178
181
|
<li><code>src/sessions/</code></li>
|
|
179
182
|
<li><code>src/traces/</code></li>
|
|
183
|
+
<li><code>src/users/</code></li>
|
|
180
184
|
<li><code>src/vitest/</code></li>
|
|
181
185
|
<li><code>src/jest/</code></li>
|
|
182
186
|
<li><code>src/testing/</code></li>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Projects"
|
|
3
|
+
description: "List projects and manage project retention-policy assignments"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The projects module lists Phoenix projects and assigns existing trace retention policies to them.
|
|
7
|
+
|
|
8
|
+
<section className="hidden" data-agent-context="relevant-source-files" aria-label="Relevant source files">
|
|
9
|
+
<h2>Relevant Source Files</h2>
|
|
10
|
+
<ul>
|
|
11
|
+
<li><code>src/projects/getProjects.ts</code></li>
|
|
12
|
+
<li><code>src/projects/setProjectRetentionPolicy.ts</code></li>
|
|
13
|
+
<li><code>src/types/projects.ts</code></li>
|
|
14
|
+
</ul>
|
|
15
|
+
</section>
|
|
16
|
+
|
|
17
|
+
## List Projects
|
|
18
|
+
|
|
19
|
+
`getProjects` handles cursor pagination automatically. Use `nameContains` for a case-insensitive, server-side substring filter.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { getProjects } from "@arizeai/phoenix-client/projects";
|
|
23
|
+
|
|
24
|
+
const projects = await getProjects({ nameContains: "support" });
|
|
25
|
+
|
|
26
|
+
for (const project of projects) {
|
|
27
|
+
console.log(`${project.name} (${project.id})`);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Assign A Retention Policy
|
|
32
|
+
|
|
33
|
+
`setProjectRetentionPolicy` accepts a project name or project GlobalID and the GlobalID of an existing trace retention policy.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { setProjectRetentionPolicy } from "@arizeai/phoenix-client/projects";
|
|
37
|
+
|
|
38
|
+
const assignment = await setProjectRetentionPolicy({
|
|
39
|
+
projectName: "support-bot",
|
|
40
|
+
policyId: "UHJvamVjdFRyYWNlUmV0ZW50aW9uUG9saWN5OjI=",
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.log(assignment.project_id, assignment.policy_id);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
You can select the project with `projectName`, `projectId`, or the shorthand `project`. `projectId` must be the project's GlobalID.
|
|
47
|
+
|
|
48
|
+
This helper only changes which existing retention policy the project uses. It does not create, read, update, or delete retention policies; policy CRUD is outside the TypeScript client's projects helper.
|
|
49
|
+
|
|
50
|
+
## Reset To The Default Policy
|
|
51
|
+
|
|
52
|
+
Pass `null` as `policyId` to remove the explicit assignment and return the project to Phoenix's default retention policy.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
await setProjectRetentionPolicy({
|
|
56
|
+
projectId: "UHJvamVjdDox",
|
|
57
|
+
policyId: null,
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Assigning or resetting a retention policy requires an admin when authentication is enabled. Invalid policy GlobalIDs produce a `422` response, while callers without permission receive `403`; both are surfaced as `HttpError` instances by the client.
|
|
62
|
+
|
|
63
|
+
<section className="hidden" data-agent-context="source-map" aria-label="Source map">
|
|
64
|
+
<h2>Source Map</h2>
|
|
65
|
+
<ul>
|
|
66
|
+
<li><code>src/projects/getProjects.ts</code></li>
|
|
67
|
+
<li><code>src/projects/setProjectRetentionPolicy.ts</code></li>
|
|
68
|
+
<li><code>src/projects/index.ts</code></li>
|
|
69
|
+
<li><code>src/types/projects.ts</code></li>
|
|
70
|
+
</ul>
|
|
71
|
+
</section>
|
package/docs/sessions.mdx
CHANGED
|
@@ -29,10 +29,19 @@ const sessions = await listSessions({
|
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
for (const session of sessions) {
|
|
32
|
-
console.log(
|
|
32
|
+
console.log({
|
|
33
|
+
sessionId: session.sessionId,
|
|
34
|
+
promptTokens: session.tokenCountPrompt,
|
|
35
|
+
completionTokens: session.tokenCountCompletion,
|
|
36
|
+
totalTokens: session.tokenCountTotal,
|
|
37
|
+
});
|
|
33
38
|
}
|
|
34
39
|
```
|
|
35
40
|
|
|
41
|
+
Each session includes cumulative prompt, completion, and total token counts across
|
|
42
|
+
all of its spans. The fields may be `undefined` when using a Phoenix server that
|
|
43
|
+
does not return session token usage.
|
|
44
|
+
|
|
36
45
|
## Retrieve A Session And Its Turns
|
|
37
46
|
|
|
38
47
|
```ts
|
package/docs/traces.mdx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Traces"
|
|
3
|
-
description: "Retrieve
|
|
3
|
+
description: "Retrieve, move, and annotate traces with @arizeai/phoenix-client"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
The traces module provides trace retrieval and trace-level annotation functions.
|
|
6
|
+
The traces module provides trace retrieval, project transfer, and trace-level annotation functions.
|
|
7
7
|
|
|
8
8
|
<section className="hidden" data-agent-context="relevant-source-files" aria-label="Relevant source files">
|
|
9
9
|
<h2>Relevant Source Files</h2>
|
|
@@ -18,6 +18,9 @@ The traces module provides trace retrieval and trace-level annotation functions.
|
|
|
18
18
|
<li>
|
|
19
19
|
<code>src/traces/logTraceAnnotations.ts</code> for batched annotation writes
|
|
20
20
|
</li>
|
|
21
|
+
<li>
|
|
22
|
+
<code>src/traces/transferTraces.ts</code> for moving traces between projects
|
|
23
|
+
</li>
|
|
21
24
|
<li>
|
|
22
25
|
<code>src/traces/types.ts</code> for the <code>TraceAnnotation</code> type
|
|
23
26
|
</li>
|
|
@@ -65,6 +68,28 @@ console.log(result.nextCursor);
|
|
|
65
68
|
- Set `includeSpans` when you need a trace-centric fetch that also contains span details
|
|
66
69
|
- `project` accepts `{ project }`, `{ projectId }`, or `{ projectName }`
|
|
67
70
|
|
|
71
|
+
## Move Traces To Another Project
|
|
72
|
+
|
|
73
|
+
Use `transferTraces` to move one or more traces from their current project to a destination project. This operation **moves rather than copies** the traces: after a successful transfer, they no longer appear in the source project.
|
|
74
|
+
|
|
75
|
+
All traces in one call must currently belong to the same source project. Each trace identifier can be either an OpenTelemetry trace ID or a Phoenix trace GlobalID, and the destination can be either a project name or project GlobalID.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { transferTraces } from "@arizeai/phoenix-client/traces";
|
|
79
|
+
|
|
80
|
+
const result = await transferTraces({
|
|
81
|
+
traceIdentifiers: ["8f3a...", "VHJhY2U6Mg=="],
|
|
82
|
+
destinationProjectIdentifier: "production",
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
console.log(`Moved ${result.transferredTraceCount} traces`);
|
|
86
|
+
console.log(`Destination project: ${result.destinationProjectId}`);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The result contains the number of distinct traces moved and the resolved GlobalID of the destination project. Phoenix rejects an empty list, trace or project identifiers that do not resolve, and requests that combine traces from multiple source projects.
|
|
90
|
+
|
|
91
|
+
`transferTraces` requires Phoenix server 20.4.0 or newer.
|
|
92
|
+
|
|
68
93
|
## Annotate a Single Trace
|
|
69
94
|
|
|
70
95
|
Use `addTraceAnnotation` to attach a label, score, or explanation to one trace. If you supply an `identifier`, Phoenix upserts the annotation when an annotation with that identifier already exists.
|
|
@@ -128,6 +153,7 @@ for (const r of results) {
|
|
|
128
153
|
<li><code>src/traces/getTraces.ts</code></li>
|
|
129
154
|
<li><code>src/traces/addTraceAnnotation.ts</code></li>
|
|
130
155
|
<li><code>src/traces/logTraceAnnotations.ts</code></li>
|
|
156
|
+
<li><code>src/traces/transferTraces.ts</code></li>
|
|
131
157
|
<li><code>src/traces/types.ts</code></li>
|
|
132
158
|
<li><code>src/types/projects.ts</code></li>
|
|
133
159
|
</ul>
|
package/docs/users.mdx
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Users"
|
|
3
|
+
description: "Get the current Phoenix user with @arizeai/phoenix-client"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The users module identifies the user associated with the client's current credentials.
|
|
7
|
+
|
|
8
|
+
## Get The Current User
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { getCurrentUser } from "@arizeai/phoenix-client/users";
|
|
12
|
+
|
|
13
|
+
const user = await getCurrentUser();
|
|
14
|
+
|
|
15
|
+
if (user.auth_method === "ANONYMOUS") {
|
|
16
|
+
console.log("Authentication is disabled");
|
|
17
|
+
} else {
|
|
18
|
+
console.log(`${user.username} has the ${user.role} role`);
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`getCurrentUser()` returns the generated Phoenix API user union. Authenticated deployments return a local, OAuth 2, or LDAP user profile. When authentication is disabled, it returns `{ auth_method: "ANONYMOUS" }`. Invalid credentials reject with an `HttpError` whose `status` is `401`; other authorization failures retain their HTTP status as well.
|
|
23
|
+
|
|
24
|
+
Pass a client explicitly when you need custom configuration:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { createClient } from "@arizeai/phoenix-client";
|
|
28
|
+
import { getCurrentUser } from "@arizeai/phoenix-client/users";
|
|
29
|
+
|
|
30
|
+
const client = createClient({
|
|
31
|
+
options: { baseUrl: "https://phoenix.example.com" },
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const user = await getCurrentUser({ client });
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
<section className="hidden" data-agent-context="source-map" aria-label="Source map">
|
|
38
|
+
<h2>Source Map</h2>
|
|
39
|
+
<ul>
|
|
40
|
+
<li><code>src/users/getCurrentUser.ts</code></li>
|
|
41
|
+
<li><code>src/users/index.ts</code></li>
|
|
42
|
+
<li><code>src/__generated__/api/v1.ts</code></li>
|
|
43
|
+
</ul>
|
|
44
|
+
</section>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arizeai/phoenix-client",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.7.1",
|
|
4
4
|
"description": "A client for the Phoenix API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"arize",
|
|
@@ -57,6 +57,10 @@
|
|
|
57
57
|
"import": "./dist/esm/projects/index.js",
|
|
58
58
|
"require": "./dist/src/projects/index.js"
|
|
59
59
|
},
|
|
60
|
+
"./users": {
|
|
61
|
+
"import": "./dist/esm/users/index.js",
|
|
62
|
+
"require": "./dist/src/users/index.js"
|
|
63
|
+
},
|
|
60
64
|
"./traces": {
|
|
61
65
|
"import": "./dist/esm/traces/index.js",
|
|
62
66
|
"require": "./dist/src/traces/index.js"
|
|
@@ -129,7 +133,7 @@
|
|
|
129
133
|
"@anthropic-ai/sdk": "^0.35.0",
|
|
130
134
|
"ai": "^7.0.0",
|
|
131
135
|
"jest": ">=27",
|
|
132
|
-
"openai": "^6.10.0",
|
|
136
|
+
"openai": "^6.10.0 || ^7.0.0",
|
|
133
137
|
"vitest": ">=1"
|
|
134
138
|
},
|
|
135
139
|
"peerDependenciesMeta": {
|
|
@@ -9987,7 +9987,7 @@ export interface operations {
|
|
|
9987
9987
|
order?: "asc" | "desc";
|
|
9988
9988
|
/** @description Maximum number of traces to return */
|
|
9989
9989
|
limit?: number;
|
|
9990
|
-
/** @description Pagination cursor
|
|
9990
|
+
/** @description Pagination cursor returned by a previous request */
|
|
9991
9991
|
cursor?: string | null;
|
|
9992
9992
|
/** @description If true, include full span details for each trace. This significantly increases response size and query latency, especially with large page sizes. Prefer fetching spans lazily for individual traces when possible. */
|
|
9993
9993
|
include_spans?: boolean;
|
|
@@ -98,6 +98,13 @@ export const LIST_PROJECT_TRACES: RouteRequirement = {
|
|
|
98
98
|
minServerVersion: [13, 15, 0],
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
+
export const TRANSFER_TRACES: RouteRequirement = {
|
|
102
|
+
kind: "route",
|
|
103
|
+
method: "POST",
|
|
104
|
+
path: "/v1/traces/transfer",
|
|
105
|
+
minServerVersion: [20, 4, 0],
|
|
106
|
+
};
|
|
107
|
+
|
|
101
108
|
export const GET_SPANS_BY_ATTRIBUTE: ParameterRequirement = {
|
|
102
109
|
kind: "parameter",
|
|
103
110
|
parameterName: "attribute",
|
|
@@ -227,6 +234,7 @@ export const ALL_REQUIREMENTS: readonly CapabilityRequirement[] = [
|
|
|
227
234
|
GET_SPANS_FILTERS,
|
|
228
235
|
GET_SPANS_BY_ATTRIBUTE,
|
|
229
236
|
LIST_PROJECT_TRACES,
|
|
237
|
+
TRANSFER_TRACES,
|
|
230
238
|
DATASET_UPLOAD_EXAMPLE_IDS,
|
|
231
239
|
ADD_TRACE_NOTE_IDENTIFIER,
|
|
232
240
|
ADD_SPAN_NOTE_IDENTIFIER,
|
|
@@ -301,6 +301,71 @@ function setupEvaluationTracer({
|
|
|
301
301
|
* });
|
|
302
302
|
* ```
|
|
303
303
|
*/
|
|
304
|
+
function isEmptyEvaluationBatch({
|
|
305
|
+
batchLength,
|
|
306
|
+
totalProcessed,
|
|
307
|
+
logger,
|
|
308
|
+
}: {
|
|
309
|
+
batchLength: number;
|
|
310
|
+
totalProcessed: number;
|
|
311
|
+
logger: Logger;
|
|
312
|
+
}): boolean {
|
|
313
|
+
if (batchLength > 0) return false;
|
|
314
|
+
if (totalProcessed === 0) {
|
|
315
|
+
logger.info(`${PROGRESS_PREFIX.completed}No incomplete evaluations found.`);
|
|
316
|
+
}
|
|
317
|
+
return true;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function shouldContinueEvaluationFetch({
|
|
321
|
+
cursor,
|
|
322
|
+
signal,
|
|
323
|
+
}: {
|
|
324
|
+
cursor: string | null;
|
|
325
|
+
signal: AbortSignal;
|
|
326
|
+
}): boolean {
|
|
327
|
+
return cursor !== null && !signal.aborted;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function getEvaluationExecutionError({
|
|
331
|
+
rejections,
|
|
332
|
+
isAborted,
|
|
333
|
+
logger,
|
|
334
|
+
}: {
|
|
335
|
+
rejections: unknown[];
|
|
336
|
+
isAborted: boolean;
|
|
337
|
+
logger: Logger;
|
|
338
|
+
}): Error | null {
|
|
339
|
+
if (rejections.length === 0) return null;
|
|
340
|
+
const fetchError = rejections.find(
|
|
341
|
+
(reason) => reason instanceof EvaluationFetchError
|
|
342
|
+
);
|
|
343
|
+
if (fetchError instanceof Error) {
|
|
344
|
+
logger.error(`Critical: Failed to fetch evaluations from server`);
|
|
345
|
+
return fetchError;
|
|
346
|
+
}
|
|
347
|
+
const workerError = rejections.find(
|
|
348
|
+
(reason) =>
|
|
349
|
+
reason instanceof Error &&
|
|
350
|
+
!(reason instanceof EvaluationFetchError) &&
|
|
351
|
+
!(reason instanceof ChannelError)
|
|
352
|
+
);
|
|
353
|
+
if (workerError instanceof Error) return workerError;
|
|
354
|
+
const channelError = rejections.find(
|
|
355
|
+
(reason) => reason instanceof ChannelError
|
|
356
|
+
);
|
|
357
|
+
if (channelError instanceof Error && isAborted) {
|
|
358
|
+
return new EvaluationAbortedError(
|
|
359
|
+
"Evaluation stopped due to error in concurrent evaluator",
|
|
360
|
+
channelError
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
const reason = rejections[0];
|
|
364
|
+
const error = reason instanceof Error ? reason : new Error(String(reason));
|
|
365
|
+
logger.error(`Unexpected error during evaluation: ${error.message}`);
|
|
366
|
+
return error;
|
|
367
|
+
}
|
|
368
|
+
|
|
304
369
|
export async function resumeEvaluation({
|
|
305
370
|
client: _client,
|
|
306
371
|
experimentId,
|
|
@@ -425,12 +490,13 @@ export async function resumeEvaluation({
|
|
|
425
490
|
const batchIncomplete = res.data?.data;
|
|
426
491
|
invariant(batchIncomplete, "Failed to fetch incomplete evaluations");
|
|
427
492
|
|
|
428
|
-
if (
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
}
|
|
493
|
+
if (
|
|
494
|
+
isEmptyEvaluationBatch({
|
|
495
|
+
batchLength: batchIncomplete.length,
|
|
496
|
+
totalProcessed,
|
|
497
|
+
logger,
|
|
498
|
+
})
|
|
499
|
+
) {
|
|
434
500
|
break;
|
|
435
501
|
}
|
|
436
502
|
|
|
@@ -468,7 +534,7 @@ export async function resumeEvaluation({
|
|
|
468
534
|
logger.debug(
|
|
469
535
|
`${PROGRESS_PREFIX.progress}Fetched batch of ${batchCount} evaluation tasks.`
|
|
470
536
|
);
|
|
471
|
-
} while (cursor
|
|
537
|
+
} while (shouldContinueEvaluationFetch({ cursor, signal }));
|
|
472
538
|
} catch (error) {
|
|
473
539
|
// Re-throw with context preservation
|
|
474
540
|
if (error instanceof EvaluationFetchError) {
|
|
@@ -547,47 +613,11 @@ export async function resumeEvaluation({
|
|
|
547
613
|
)
|
|
548
614
|
.map((result) => result.reason);
|
|
549
615
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
const fetchError = rejections.find(
|
|
556
|
-
(reason) => reason instanceof EvaluationFetchError
|
|
557
|
-
);
|
|
558
|
-
const workerError = rejections.find(
|
|
559
|
-
(reason) =>
|
|
560
|
-
reason instanceof Error &&
|
|
561
|
-
!(reason instanceof EvaluationFetchError) &&
|
|
562
|
-
!(reason instanceof ChannelError)
|
|
563
|
-
);
|
|
564
|
-
const channelError = rejections.find(
|
|
565
|
-
(reason) => reason instanceof ChannelError
|
|
566
|
-
);
|
|
567
|
-
|
|
568
|
-
if (fetchError) {
|
|
569
|
-
// Producer failed - this is ALWAYS critical regardless of stopOnFirstError
|
|
570
|
-
logger.error(`Critical: Failed to fetch evaluations from server`);
|
|
571
|
-
executionError = fetchError;
|
|
572
|
-
} else if (workerError) {
|
|
573
|
-
// Worker error in stopOnFirstError mode - already logged by worker
|
|
574
|
-
executionError = workerError;
|
|
575
|
-
} else if (channelError && signal.aborted) {
|
|
576
|
-
// Channel closed due to intentional abort - wrap in semantic error
|
|
577
|
-
executionError = new EvaluationAbortedError(
|
|
578
|
-
"Evaluation stopped due to error in concurrent evaluator",
|
|
579
|
-
channelError
|
|
580
|
-
);
|
|
581
|
-
} else {
|
|
582
|
-
// Unexpected error (not from worker, not from producer fetch)
|
|
583
|
-
// This could be a bug in our code or infrastructure failure
|
|
584
|
-
const reason = rejections[0];
|
|
585
|
-
const err =
|
|
586
|
-
reason instanceof Error ? reason : new Error(String(reason));
|
|
587
|
-
logger.error(`Unexpected error during evaluation: ${err.message}`);
|
|
588
|
-
executionError = err;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
616
|
+
executionError = getEvaluationExecutionError({
|
|
617
|
+
rejections,
|
|
618
|
+
isAborted: signal.aborted,
|
|
619
|
+
logger,
|
|
620
|
+
});
|
|
591
621
|
} finally {
|
|
592
622
|
// Ensure channel is closed even if there are unexpected errors
|
|
593
623
|
// This is a safety net in case producer's finally block didn't execute
|
|
@@ -276,6 +276,67 @@ function setupTracer({
|
|
|
276
276
|
* });
|
|
277
277
|
* ```
|
|
278
278
|
*/
|
|
279
|
+
function getResumeEvaluators({
|
|
280
|
+
evaluators,
|
|
281
|
+
executionError,
|
|
282
|
+
}: {
|
|
283
|
+
evaluators: readonly ExperimentEvaluatorLike[] | undefined;
|
|
284
|
+
executionError: Error | null;
|
|
285
|
+
}): readonly ExperimentEvaluatorLike[] | null {
|
|
286
|
+
return evaluators && evaluators.length > 0 && !executionError
|
|
287
|
+
? evaluators
|
|
288
|
+
: null;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function shouldWarnAboutFailedRuns({
|
|
292
|
+
totalFailed,
|
|
293
|
+
executionError,
|
|
294
|
+
}: {
|
|
295
|
+
totalFailed: number;
|
|
296
|
+
executionError: Error | null;
|
|
297
|
+
}): boolean {
|
|
298
|
+
return totalFailed > 0 && !executionError;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function getTaskExecutionError({
|
|
302
|
+
rejections,
|
|
303
|
+
isAborted,
|
|
304
|
+
logger,
|
|
305
|
+
}: {
|
|
306
|
+
rejections: unknown[];
|
|
307
|
+
isAborted: boolean;
|
|
308
|
+
logger: Logger;
|
|
309
|
+
}): Error | null {
|
|
310
|
+
if (rejections.length === 0) return null;
|
|
311
|
+
const fetchError = rejections.find(
|
|
312
|
+
(reason) => reason instanceof TaskFetchError
|
|
313
|
+
);
|
|
314
|
+
if (fetchError instanceof Error) {
|
|
315
|
+
logger.error(`Critical: Failed to fetch incomplete runs from server`);
|
|
316
|
+
return fetchError;
|
|
317
|
+
}
|
|
318
|
+
const taskError = rejections.find(
|
|
319
|
+
(reason) =>
|
|
320
|
+
reason instanceof Error &&
|
|
321
|
+
!(reason instanceof TaskFetchError) &&
|
|
322
|
+
!(reason instanceof ChannelError)
|
|
323
|
+
);
|
|
324
|
+
if (taskError instanceof Error) return taskError;
|
|
325
|
+
const channelError = rejections.find(
|
|
326
|
+
(reason) => reason instanceof ChannelError
|
|
327
|
+
);
|
|
328
|
+
if (channelError instanceof Error && isAborted) {
|
|
329
|
+
return new TaskAbortedError(
|
|
330
|
+
"Task execution stopped due to error in concurrent worker",
|
|
331
|
+
channelError
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
const reason = rejections[0];
|
|
335
|
+
const error = reason instanceof Error ? reason : new Error(String(reason));
|
|
336
|
+
logger.error(`Unexpected error during task execution: ${error.message}`);
|
|
337
|
+
return error;
|
|
338
|
+
}
|
|
339
|
+
|
|
279
340
|
export async function resumeExperiment({
|
|
280
341
|
client: _client,
|
|
281
342
|
experimentId,
|
|
@@ -514,49 +575,11 @@ export async function resumeExperiment({
|
|
|
514
575
|
)
|
|
515
576
|
.map((result) => result.reason);
|
|
516
577
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
const fetchError = rejections.find(
|
|
523
|
-
(reason) => reason instanceof TaskFetchError
|
|
524
|
-
);
|
|
525
|
-
const taskError = rejections.find(
|
|
526
|
-
(reason) =>
|
|
527
|
-
reason instanceof Error &&
|
|
528
|
-
!(reason instanceof TaskFetchError) &&
|
|
529
|
-
!(reason instanceof ChannelError)
|
|
530
|
-
);
|
|
531
|
-
const channelError = rejections.find(
|
|
532
|
-
(reason) => reason instanceof ChannelError
|
|
533
|
-
);
|
|
534
|
-
|
|
535
|
-
if (fetchError) {
|
|
536
|
-
// Producer failed - this is ALWAYS critical regardless of stopOnFirstError
|
|
537
|
-
logger.error(`Critical: Failed to fetch incomplete runs from server`);
|
|
538
|
-
executionError = fetchError;
|
|
539
|
-
} else if (taskError) {
|
|
540
|
-
// Worker error in stopOnFirstError mode - already logged by worker
|
|
541
|
-
executionError = taskError;
|
|
542
|
-
} else if (channelError && signal.aborted) {
|
|
543
|
-
// Channel closed due to intentional abort - wrap in semantic error
|
|
544
|
-
executionError = new TaskAbortedError(
|
|
545
|
-
"Task execution stopped due to error in concurrent worker",
|
|
546
|
-
channelError
|
|
547
|
-
);
|
|
548
|
-
} else {
|
|
549
|
-
// Unexpected error (not from worker, not from producer fetch)
|
|
550
|
-
// This could be a bug in our code or infrastructure failure
|
|
551
|
-
const reason = rejections[0];
|
|
552
|
-
const err =
|
|
553
|
-
reason instanceof Error ? reason : new Error(String(reason));
|
|
554
|
-
logger.error(
|
|
555
|
-
`Unexpected error during task execution: ${err.message}`
|
|
556
|
-
);
|
|
557
|
-
executionError = err;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
578
|
+
executionError = getTaskExecutionError({
|
|
579
|
+
rejections,
|
|
580
|
+
isAborted: signal.aborted,
|
|
581
|
+
logger,
|
|
582
|
+
});
|
|
560
583
|
} finally {
|
|
561
584
|
// Ensure channel is closed even if there are unexpected errors
|
|
562
585
|
// This is a safety net in case producer's finally block didn't execute
|
|
@@ -570,11 +593,15 @@ export async function resumeExperiment({
|
|
|
570
593
|
logger.info(`${PROGRESS_PREFIX.completed}Task runs completed.`);
|
|
571
594
|
}
|
|
572
595
|
|
|
573
|
-
if (totalFailed
|
|
596
|
+
if (shouldWarnAboutFailedRuns({ totalFailed, executionError })) {
|
|
574
597
|
logger.warn(`${totalFailed} out of ${totalProcessed} runs failed.`);
|
|
575
598
|
}
|
|
576
599
|
|
|
577
|
-
|
|
600
|
+
const resumeEvaluators = getResumeEvaluators({
|
|
601
|
+
evaluators,
|
|
602
|
+
executionError,
|
|
603
|
+
});
|
|
604
|
+
if (resumeEvaluators) {
|
|
578
605
|
await cleanupOwnedTracerProvider({
|
|
579
606
|
provider,
|
|
580
607
|
globalRegistration,
|
|
@@ -585,7 +612,7 @@ export async function resumeExperiment({
|
|
|
585
612
|
logger.info(`${PROGRESS_PREFIX.start}Running evaluators.`);
|
|
586
613
|
await resumeEvaluation({
|
|
587
614
|
experimentId,
|
|
588
|
-
evaluators: [...
|
|
615
|
+
evaluators: [...resumeEvaluators],
|
|
589
616
|
client,
|
|
590
617
|
logger,
|
|
591
618
|
concurrency,
|