@arizeai/phoenix-client 7.2.0 → 7.3.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/README.md +3 -2
- package/dist/esm/__generated__/api/v1.d.ts +548 -0
- package/dist/esm/__generated__/api/v1.d.ts.map +1 -1
- package/dist/esm/client.d.ts +10 -2
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +6 -0
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/config.d.ts +10 -0
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +13 -9
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/experiments/resumeEvaluation.d.ts.map +1 -1
- package/dist/esm/experiments/resumeEvaluation.js +5 -5
- package/dist/esm/experiments/resumeEvaluation.js.map +1 -1
- package/dist/esm/experiments/resumeExperiment.d.ts.map +1 -1
- package/dist/esm/experiments/resumeExperiment.js +5 -5
- 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 +5 -5
- package/dist/esm/experiments/runExperiment.js.map +1 -1
- package/dist/esm/experiments/tracing.d.ts +27 -0
- package/dist/esm/experiments/tracing.d.ts.map +1 -1
- package/dist/esm/experiments/tracing.js +27 -0
- package/dist/esm/experiments/tracing.js.map +1 -1
- package/dist/esm/testing/phoenix-test-tracking.d.ts.map +1 -1
- package/dist/esm/testing/phoenix-test-tracking.js +9 -9
- package/dist/esm/testing/phoenix-test-tracking.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/src/__generated__/api/v1.d.ts +548 -0
- package/dist/src/__generated__/api/v1.d.ts.map +1 -1
- package/dist/src/client.d.ts +10 -2
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +6 -1
- package/dist/src/client.js.map +1 -1
- package/dist/src/config.d.ts +10 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +11 -7
- package/dist/src/config.js.map +1 -1
- package/dist/src/experiments/resumeEvaluation.d.ts.map +1 -1
- package/dist/src/experiments/resumeEvaluation.js +4 -4
- package/dist/src/experiments/resumeEvaluation.js.map +1 -1
- package/dist/src/experiments/resumeExperiment.d.ts.map +1 -1
- package/dist/src/experiments/resumeExperiment.js +4 -4
- 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 +4 -4
- package/dist/src/experiments/runExperiment.js.map +1 -1
- package/dist/src/experiments/tracing.d.ts +27 -0
- package/dist/src/experiments/tracing.d.ts.map +1 -1
- package/dist/src/experiments/tracing.js +30 -0
- package/dist/src/experiments/tracing.js.map +1 -1
- package/dist/src/testing/phoenix-test-tracking.d.ts.map +1 -1
- package/dist/src/testing/phoenix-test-tracking.js +8 -8
- package/dist/src/testing/phoenix-test-tracking.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/ci-evals-jest.mdx +1 -1
- package/docs/ci-evals-vitest.mdx +1 -1
- package/docs/ci-evals.mdx +1 -1
- package/docs/overview.mdx +5 -5
- package/package.json +9 -9
- package/src/__generated__/api/v1.ts +548 -0
- package/src/client.ts +17 -1
- package/src/config.ts +28 -11
- package/src/experiments/resumeEvaluation.ts +11 -9
- package/src/experiments/resumeExperiment.ts +11 -9
- package/src/experiments/runExperiment.ts +9 -11
- package/src/experiments/tracing.ts +35 -0
- package/src/testing/phoenix-test-tracking.ts +12 -9
package/src/config.ts
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
import type { EnvironmentConfig } from "@arizeai/phoenix-config";
|
|
2
1
|
import {
|
|
3
2
|
DEFAULT_PHOENIX_BASE_URL,
|
|
4
|
-
|
|
3
|
+
getBaseUrlFromEnvironment,
|
|
4
|
+
getCredentialsFromEnvironment,
|
|
5
5
|
} from "@arizeai/phoenix-config";
|
|
6
6
|
import type { ClientOptions } from "openapi-fetch";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Convert
|
|
9
|
+
* Convert resolved Phoenix credentials into a ClientOptions object.
|
|
10
10
|
*
|
|
11
|
-
* @param
|
|
11
|
+
* @param credentials - The API key and headers resolved from the environment.
|
|
12
12
|
* @returns The converted ClientOptions object.
|
|
13
13
|
*/
|
|
14
|
-
const
|
|
15
|
-
|
|
14
|
+
const phoenixCredentialsToClientOptions = (
|
|
15
|
+
credentials: ReturnType<typeof getCredentialsFromEnvironment>
|
|
16
16
|
): Partial<ClientOptions> => {
|
|
17
17
|
const options: Partial<ClientOptions> = {
|
|
18
|
-
baseUrl: environment.PHOENIX_HOST,
|
|
19
18
|
headers: {
|
|
20
|
-
...(
|
|
21
|
-
...(
|
|
22
|
-
? { Authorization: `Bearer ${
|
|
19
|
+
...(credentials.headers ?? {}),
|
|
20
|
+
...(credentials.apiKey
|
|
21
|
+
? { Authorization: `Bearer ${credentials.apiKey}` }
|
|
23
22
|
: {}),
|
|
24
23
|
},
|
|
25
24
|
};
|
|
@@ -36,6 +35,17 @@ const phoenixEnvironmentToClientOptions = (
|
|
|
36
35
|
);
|
|
37
36
|
};
|
|
38
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Where a client's base URL came from: an explicit `baseUrl` option
|
|
40
|
+
* (`"explicit"`), a Phoenix environment variable (`"environment"`), or the
|
|
41
|
+
* built-in localhost default (`"default"`).
|
|
42
|
+
*
|
|
43
|
+
* Explicit configuration outranks the ambient environment, so this is what
|
|
44
|
+
* decides whether an environment variable may retarget the client's trace
|
|
45
|
+
* export.
|
|
46
|
+
*/
|
|
47
|
+
export type BaseUrlSource = "default" | "environment" | "explicit";
|
|
48
|
+
|
|
39
49
|
/**
|
|
40
50
|
* Get the environment options from the environment.
|
|
41
51
|
*
|
|
@@ -46,7 +56,14 @@ export const defaultGetEnvironmentOptions = (): Partial<ClientOptions> => {
|
|
|
46
56
|
if (typeof process !== "object" || typeof process.env !== "object") {
|
|
47
57
|
return {};
|
|
48
58
|
}
|
|
49
|
-
|
|
59
|
+
const options = phoenixCredentialsToClientOptions(
|
|
60
|
+
getCredentialsFromEnvironment()
|
|
61
|
+
);
|
|
62
|
+
// The base URL resolves as a tier group (PHOENIX_ENDPOINT first, inferring
|
|
63
|
+
// from the trace-export variables, then legacy PHOENIX_HOST) rather than
|
|
64
|
+
// variable by variable.
|
|
65
|
+
const baseUrl = getBaseUrlFromEnvironment();
|
|
66
|
+
return baseUrl !== undefined ? { ...options, baseUrl } : options;
|
|
50
67
|
};
|
|
51
68
|
|
|
52
69
|
/**
|
|
@@ -31,7 +31,11 @@ import { getExperimentInfo } from "./getExperimentInfo.js";
|
|
|
31
31
|
import { getExperimentEvaluators } from "./helpers";
|
|
32
32
|
import { getExampleGlobalId } from "./helpers/getExampleGlobalId";
|
|
33
33
|
import { logEvalResumeSummary, PROGRESS_PREFIX } from "./logging";
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
cleanupOwnedTracerProvider,
|
|
36
|
+
getTraceExportUrl,
|
|
37
|
+
MISSING_BASE_URL_MESSAGE,
|
|
38
|
+
} from "./tracing";
|
|
35
39
|
|
|
36
40
|
/**
|
|
37
41
|
* Error thrown when evaluation is aborted due to a failure in stopOnFirstError mode.
|
|
@@ -199,14 +203,15 @@ async function handleEvaluationFetchError(
|
|
|
199
203
|
*/
|
|
200
204
|
function setupEvaluationTracer({
|
|
201
205
|
projectName,
|
|
202
|
-
|
|
206
|
+
traceExportUrl,
|
|
203
207
|
headers,
|
|
204
208
|
useBatchSpanProcessor,
|
|
205
209
|
diagLogLevel,
|
|
206
210
|
setGlobalTracerProvider,
|
|
207
211
|
}: {
|
|
208
212
|
projectName: string | null;
|
|
209
|
-
|
|
213
|
+
/** Where spans are exported; omit to let `register()` read the environment. */
|
|
214
|
+
traceExportUrl?: string;
|
|
210
215
|
headers?: Record<string, string>;
|
|
211
216
|
useBatchSpanProcessor: boolean;
|
|
212
217
|
diagLogLevel?: DiagLogLevel;
|
|
@@ -222,7 +227,7 @@ function setupEvaluationTracer({
|
|
|
222
227
|
|
|
223
228
|
const provider = register({
|
|
224
229
|
projectName,
|
|
225
|
-
url:
|
|
230
|
+
url: traceExportUrl,
|
|
226
231
|
headers,
|
|
227
232
|
batch: useBatchSpanProcessor,
|
|
228
233
|
diagLogLevel,
|
|
@@ -323,14 +328,11 @@ export async function resumeEvaluation({
|
|
|
323
328
|
|
|
324
329
|
// Initialize tracer (only if experiment has a project_name)
|
|
325
330
|
const baseUrl = client.config.baseUrl;
|
|
326
|
-
invariant(
|
|
327
|
-
baseUrl,
|
|
328
|
-
"Phoenix base URL not found. Please set PHOENIX_HOST or set baseUrl on the client."
|
|
329
|
-
);
|
|
331
|
+
invariant(baseUrl, MISSING_BASE_URL_MESSAGE);
|
|
330
332
|
|
|
331
333
|
const tracerSetup = setupEvaluationTracer({
|
|
332
334
|
projectName: experiment.projectName,
|
|
333
|
-
|
|
335
|
+
traceExportUrl: getTraceExportUrl(client.config),
|
|
334
336
|
headers: client.config.headers
|
|
335
337
|
? toObjectHeaders(client.config.headers)
|
|
336
338
|
: undefined,
|
|
@@ -35,7 +35,11 @@ import {
|
|
|
35
35
|
PROGRESS_PREFIX,
|
|
36
36
|
} from "./logging";
|
|
37
37
|
import { resumeEvaluation } from "./resumeEvaluation";
|
|
38
|
-
import {
|
|
38
|
+
import {
|
|
39
|
+
cleanupOwnedTracerProvider,
|
|
40
|
+
getTraceExportUrl,
|
|
41
|
+
MISSING_BASE_URL_MESSAGE,
|
|
42
|
+
} from "./tracing";
|
|
39
43
|
|
|
40
44
|
/**
|
|
41
45
|
* Error thrown when task is aborted due to a failure in stopOnFirstError mode.
|
|
@@ -182,14 +186,15 @@ async function handleFetchError(
|
|
|
182
186
|
*/
|
|
183
187
|
function setupTracer({
|
|
184
188
|
projectName,
|
|
185
|
-
|
|
189
|
+
traceExportUrl,
|
|
186
190
|
headers,
|
|
187
191
|
useBatchSpanProcessor,
|
|
188
192
|
diagLogLevel,
|
|
189
193
|
setGlobalTracerProvider,
|
|
190
194
|
}: {
|
|
191
195
|
projectName: string | null;
|
|
192
|
-
|
|
196
|
+
/** Where spans are exported; omit to let `register()` read the environment. */
|
|
197
|
+
traceExportUrl?: string;
|
|
193
198
|
headers?: Record<string, string>;
|
|
194
199
|
useBatchSpanProcessor: boolean;
|
|
195
200
|
diagLogLevel?: DiagLogLevel;
|
|
@@ -205,7 +210,7 @@ function setupTracer({
|
|
|
205
210
|
|
|
206
211
|
const provider = register({
|
|
207
212
|
projectName,
|
|
208
|
-
url:
|
|
213
|
+
url: traceExportUrl,
|
|
209
214
|
headers,
|
|
210
215
|
batch: useBatchSpanProcessor,
|
|
211
216
|
diagLogLevel,
|
|
@@ -307,15 +312,12 @@ export async function resumeExperiment({
|
|
|
307
312
|
|
|
308
313
|
// Get base URL for tracing and URL generation
|
|
309
314
|
const baseUrl = client.config.baseUrl;
|
|
310
|
-
invariant(
|
|
311
|
-
baseUrl,
|
|
312
|
-
"Phoenix base URL not found. Please set PHOENIX_HOST or set baseUrl on the client."
|
|
313
|
-
);
|
|
315
|
+
invariant(baseUrl, MISSING_BASE_URL_MESSAGE);
|
|
314
316
|
|
|
315
317
|
// Initialize tracer (only if experiment has a project_name)
|
|
316
318
|
const tracerSetup = setupTracer({
|
|
317
319
|
projectName: experiment.projectName,
|
|
318
|
-
|
|
320
|
+
traceExportUrl: getTraceExportUrl(client.config),
|
|
319
321
|
headers: client.config.headers
|
|
320
322
|
? toObjectHeaders(client.config.headers)
|
|
321
323
|
: undefined,
|
|
@@ -54,7 +54,11 @@ import {
|
|
|
54
54
|
logTaskSummary,
|
|
55
55
|
PROGRESS_PREFIX,
|
|
56
56
|
} from "./logging";
|
|
57
|
-
import {
|
|
57
|
+
import {
|
|
58
|
+
cleanupOwnedTracerProvider,
|
|
59
|
+
getTraceExportUrl,
|
|
60
|
+
MISSING_BASE_URL_MESSAGE,
|
|
61
|
+
} from "./tracing";
|
|
58
62
|
|
|
59
63
|
/**
|
|
60
64
|
* Validate that a repetition is valid
|
|
@@ -270,14 +274,11 @@ export async function runExperiment({
|
|
|
270
274
|
};
|
|
271
275
|
// Initialize the tracer, now that we have a project name
|
|
272
276
|
const baseUrl = client.config.baseUrl;
|
|
273
|
-
invariant(
|
|
274
|
-
baseUrl,
|
|
275
|
-
"Phoenix base URL not found. Please set PHOENIX_HOST or set baseUrl on the client."
|
|
276
|
-
);
|
|
277
|
+
invariant(baseUrl, MISSING_BASE_URL_MESSAGE);
|
|
277
278
|
|
|
278
279
|
taskProvider = register({
|
|
279
280
|
projectName,
|
|
280
|
-
url:
|
|
281
|
+
url: getTraceExportUrl(client.config),
|
|
281
282
|
headers: client.config.headers
|
|
282
283
|
? toObjectHeaders(client.config.headers)
|
|
283
284
|
: undefined,
|
|
@@ -621,10 +622,7 @@ export async function evaluateExperiment({
|
|
|
621
622
|
const isDryRun = typeof dryRun === "number" || dryRun === true;
|
|
622
623
|
const client = _client ?? createClient();
|
|
623
624
|
const baseUrl = client.config.baseUrl;
|
|
624
|
-
invariant(
|
|
625
|
-
baseUrl,
|
|
626
|
-
"Phoenix base URL not found. Please set PHOENIX_HOST or set baseUrl on the client."
|
|
627
|
-
);
|
|
625
|
+
invariant(baseUrl, MISSING_BASE_URL_MESSAGE);
|
|
628
626
|
let provider: NodeTracerProvider;
|
|
629
627
|
let globalRegistration: GlobalTracerProviderRegistration | null = null;
|
|
630
628
|
const ownsProvider = !paramsTracerProvider;
|
|
@@ -635,7 +633,7 @@ export async function evaluateExperiment({
|
|
|
635
633
|
} else if (!isDryRun) {
|
|
636
634
|
provider = register({
|
|
637
635
|
projectName: "evaluators",
|
|
638
|
-
url:
|
|
636
|
+
url: getTraceExportUrl(client.config),
|
|
639
637
|
headers: client.config.headers
|
|
640
638
|
? toObjectHeaders(client.config.headers)
|
|
641
639
|
: undefined,
|
|
@@ -3,6 +3,41 @@ import type {
|
|
|
3
3
|
NodeTracerProvider,
|
|
4
4
|
} from "@arizeai/phoenix-otel";
|
|
5
5
|
|
|
6
|
+
import type { BaseUrlSource } from "../config";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Message for the invariant shared by every experiment entry point: a base URL
|
|
10
|
+
* must be resolvable before a tracer can be registered.
|
|
11
|
+
*/
|
|
12
|
+
export const MISSING_BASE_URL_MESSAGE =
|
|
13
|
+
"Phoenix base URL not found. Please set PHOENIX_ENDPOINT (or PHOENIX_COLLECTOR_ENDPOINT) or set baseUrl on the client.";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Resolves the URL experiment spans are exported to, as the `url` argument to
|
|
17
|
+
* `register()`.
|
|
18
|
+
*
|
|
19
|
+
* Explicit code-level configuration outranks the ambient environment: a client
|
|
20
|
+
* created with an explicit `baseUrl` exports its spans to that server, so a
|
|
21
|
+
* `PHOENIX_COLLECTOR_ENDPOINT` left in the shell cannot silently retarget it.
|
|
22
|
+
* When the base URL itself came from the environment, so does trace export:
|
|
23
|
+
* returning `undefined` hands resolution to `register()`, which reads the
|
|
24
|
+
* trace-export chain (`PHOENIX_COLLECTOR_ENDPOINT`, the OTel-standard
|
|
25
|
+
* variables, then `PHOENIX_ENDPOINT`) exactly as a standalone `register()`
|
|
26
|
+
* call would.
|
|
27
|
+
*
|
|
28
|
+
* A base URL of unknown provenance — a hand-built client rather than one from
|
|
29
|
+
* `createClient()` — counts as explicit, since only deliberate configuration
|
|
30
|
+
* puts a URL there.
|
|
31
|
+
*/
|
|
32
|
+
export function getTraceExportUrl(config: {
|
|
33
|
+
baseUrl?: string;
|
|
34
|
+
baseUrlSource?: BaseUrlSource;
|
|
35
|
+
}): string | undefined {
|
|
36
|
+
return (config.baseUrlSource ?? "explicit") === "explicit"
|
|
37
|
+
? config.baseUrl
|
|
38
|
+
: undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
6
41
|
/**
|
|
7
42
|
* Flushes and shuts down a tracer provider that this package created, then
|
|
8
43
|
* detaches any global OTEL registration it owns so another provider can be mounted.
|
|
@@ -16,7 +16,10 @@ import {
|
|
|
16
16
|
import type { Span } from "@opentelemetry/api";
|
|
17
17
|
|
|
18
18
|
import { createDataset } from "../datasets";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
cleanupOwnedTracerProvider,
|
|
21
|
+
getTraceExportUrl,
|
|
22
|
+
} from "../experiments/tracing";
|
|
20
23
|
import { createClient, type PhoenixClient } from "../index";
|
|
21
24
|
import { ensureString } from "../utils/ensureString";
|
|
22
25
|
import { toObjectHeaders } from "../utils/toObjectHeaders";
|
|
@@ -163,9 +166,9 @@ interface TaskSpanLifecycle {
|
|
|
163
166
|
const taskSpansByRun = new WeakMap<RunState, TaskSpanLifecycle>();
|
|
164
167
|
|
|
165
168
|
/**
|
|
166
|
-
* Warn once when
|
|
167
|
-
* header is being forwarded to the OTLP exporter — that
|
|
168
|
-
* exfiltrates the bearer token in cleartext.
|
|
169
|
+
* Warn once when the resolved base URL is plain `http:` while an
|
|
170
|
+
* `Authorization` header is being forwarded to the OTLP exporter — that
|
|
171
|
+
* combination exfiltrates the bearer token in cleartext.
|
|
169
172
|
*/
|
|
170
173
|
let warnedAboutHttpScheme = false;
|
|
171
174
|
function maybeWarnHttpScheme(
|
|
@@ -191,9 +194,9 @@ function maybeWarnHttpScheme(
|
|
|
191
194
|
warnedAboutHttpScheme = true;
|
|
192
195
|
// eslint-disable-next-line no-console
|
|
193
196
|
console.warn(
|
|
194
|
-
`[@arizeai/phoenix-client]
|
|
195
|
-
`an Authorization header set; the bearer token will travel in
|
|
196
|
-
`Use https:// for non-localhost Phoenix endpoints.`
|
|
197
|
+
`[@arizeai/phoenix-client] The Phoenix base URL "${baseUrl}" uses http:// ` +
|
|
198
|
+
`with an Authorization header set; the bearer token will travel in ` +
|
|
199
|
+
`cleartext. Use https:// for non-localhost Phoenix endpoints.`
|
|
197
200
|
);
|
|
198
201
|
}
|
|
199
202
|
|
|
@@ -349,7 +352,7 @@ export async function initializeSuite(suite: SuiteState): Promise<void> {
|
|
|
349
352
|
if (!baseUrl) {
|
|
350
353
|
suite.trackingDisabled = true;
|
|
351
354
|
suite.setupError = new Error(
|
|
352
|
-
"Phoenix base URL not found. Set
|
|
355
|
+
"Phoenix base URL not found. Set PHOENIX_ENDPOINT (or PHOENIX_COLLECTOR_ENDPOINT) or pass baseUrl on the client."
|
|
353
356
|
);
|
|
354
357
|
suite.tracer = createNoOpProvider().getTracer("no-op");
|
|
355
358
|
suite.evaluatorTracer = suite.tracer;
|
|
@@ -362,7 +365,7 @@ export async function initializeSuite(suite: SuiteState): Promise<void> {
|
|
|
362
365
|
try {
|
|
363
366
|
provider = register({
|
|
364
367
|
projectName: suite.projectName,
|
|
365
|
-
url:
|
|
368
|
+
url: getTraceExportUrl(client.config),
|
|
366
369
|
headers: client.config.headers
|
|
367
370
|
? toObjectHeaders(client.config.headers)
|
|
368
371
|
: undefined,
|