@arizeai/phoenix-client 7.7.0 → 7.8.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/CHANGELOG.md +12 -0
- package/dist/esm/__generated__/api/v1.d.ts +127 -6
- package/dist/esm/__generated__/api/v1.d.ts.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/prompts/constants.d.ts.map +1 -1
- package/dist/esm/prompts/constants.js +1 -0
- package/dist/esm/prompts/constants.js.map +1 -1
- package/dist/esm/prompts/sdks/toOpenAI.d.ts.map +1 -1
- package/dist/esm/prompts/sdks/toOpenAI.js +51 -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/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types/prompts.d.ts +1 -1
- package/dist/esm/types/prompts.d.ts.map +1 -1
- package/dist/esm/types/prompts.js.map +1 -1
- package/dist/esm/types/sessions.d.ts +6 -0
- package/dist/esm/types/sessions.d.ts.map +1 -1
- package/dist/esm/utils/getPromptBySelector.d.ts +1 -1
- package/dist/src/__generated__/api/v1.d.ts +127 -6
- package/dist/src/__generated__/api/v1.d.ts.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/prompts/constants.d.ts.map +1 -1
- package/dist/src/prompts/constants.js +1 -0
- package/dist/src/prompts/constants.js.map +1 -1
- package/dist/src/prompts/sdks/toOpenAI.d.ts.map +1 -1
- package/dist/src/prompts/sdks/toOpenAI.js +58 -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/types/prompts.d.ts +1 -1
- package/dist/src/types/prompts.d.ts.map +1 -1
- package/dist/src/types/prompts.js.map +1 -1
- package/dist/src/types/sessions.d.ts +6 -0
- package/dist/src/types/sessions.d.ts.map +1 -1
- package/dist/src/utils/getPromptBySelector.d.ts +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/sessions.mdx +10 -1
- package/package.json +1 -1
- package/src/__generated__/api/v1.ts +127 -6
- package/src/experiments/resumeEvaluation.ts +78 -48
- package/src/experiments/resumeExperiment.ts +73 -46
- package/src/experiments/runExperiment.ts +235 -129
- package/src/prompts/constants.ts +1 -0
- package/src/prompts/sdks/toOpenAI.ts +60 -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/types/prompts.ts +2 -1
- package/src/types/sessions.ts +6 -0
package/src/spans/getSpans.ts
CHANGED
|
@@ -155,28 +155,23 @@ export type GetSpansResult = {
|
|
|
155
155
|
* } while (cursor);
|
|
156
156
|
* ```
|
|
157
157
|
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
limit = 100,
|
|
163
|
-
startTime,
|
|
164
|
-
endTime,
|
|
158
|
+
type SpansQuery = NonNullable<operations["getSpans"]["parameters"]["query"]>;
|
|
159
|
+
|
|
160
|
+
async function ensureSpanFilterCapabilities({
|
|
161
|
+
client,
|
|
165
162
|
traceIds,
|
|
166
163
|
spanIds,
|
|
167
|
-
parentId,
|
|
168
164
|
name,
|
|
169
165
|
spanKind,
|
|
170
166
|
statusCode,
|
|
171
|
-
|
|
172
|
-
}:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
: undefined;
|
|
167
|
+
attributeFilters,
|
|
168
|
+
}: Pick<
|
|
169
|
+
GetSpansParams,
|
|
170
|
+
"traceIds" | "spanIds" | "name" | "spanKind" | "statusCode"
|
|
171
|
+
> & {
|
|
172
|
+
client: NonNullable<GetSpansParams["client"]>;
|
|
173
|
+
attributeFilters: string[] | undefined;
|
|
174
|
+
}): Promise<void> {
|
|
180
175
|
if (traceIds) {
|
|
181
176
|
await ensureServerCapability({ client, requirement: GET_SPANS_TRACE_IDS });
|
|
182
177
|
}
|
|
@@ -186,58 +181,99 @@ export async function getSpans({
|
|
|
186
181
|
if (name != null || spanKind != null || statusCode != null) {
|
|
187
182
|
await ensureServerCapability({ client, requirement: GET_SPANS_FILTERS });
|
|
188
183
|
}
|
|
189
|
-
if (attributeFilters
|
|
184
|
+
if (attributeFilters) {
|
|
190
185
|
await ensureServerCapability({
|
|
191
186
|
client,
|
|
192
187
|
requirement: GET_SPANS_BY_ATTRIBUTE,
|
|
193
188
|
});
|
|
194
189
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const params: NonNullable<operations["getSpans"]["parameters"]["query"]> = {
|
|
198
|
-
limit,
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
if (cursor) {
|
|
202
|
-
params.cursor = cursor;
|
|
203
|
-
}
|
|
190
|
+
}
|
|
204
191
|
|
|
192
|
+
function buildSpansQuery({
|
|
193
|
+
cursor,
|
|
194
|
+
limit,
|
|
195
|
+
startTime,
|
|
196
|
+
endTime,
|
|
197
|
+
traceIds,
|
|
198
|
+
spanIds,
|
|
199
|
+
parentId,
|
|
200
|
+
name,
|
|
201
|
+
spanKind,
|
|
202
|
+
statusCode,
|
|
203
|
+
attributeFilters,
|
|
204
|
+
}: Omit<GetSpansParams, "client" | "project" | "attributes"> & {
|
|
205
|
+
limit: number;
|
|
206
|
+
attributeFilters: string[] | undefined;
|
|
207
|
+
}): SpansQuery {
|
|
208
|
+
const params: SpansQuery = { limit };
|
|
209
|
+
if (cursor) params.cursor = cursor;
|
|
205
210
|
if (startTime) {
|
|
206
211
|
params.start_time =
|
|
207
212
|
startTime instanceof Date ? startTime.toISOString() : startTime;
|
|
208
213
|
}
|
|
209
|
-
|
|
210
214
|
if (endTime) {
|
|
211
215
|
params.end_time = endTime instanceof Date ? endTime.toISOString() : endTime;
|
|
212
216
|
}
|
|
213
|
-
|
|
214
|
-
if (
|
|
215
|
-
params.trace_id = traceIds;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (spanIds) {
|
|
219
|
-
params.span_id = spanIds;
|
|
220
|
-
}
|
|
221
|
-
|
|
217
|
+
if (traceIds) params.trace_id = traceIds;
|
|
218
|
+
if (spanIds) params.span_id = spanIds;
|
|
222
219
|
if (parentId !== undefined) {
|
|
223
220
|
params.parent_id = parentId === null ? "null" : parentId;
|
|
224
221
|
}
|
|
225
|
-
|
|
226
|
-
if (
|
|
227
|
-
params.name = Array.isArray(name) ? name : [name];
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (spanKind) {
|
|
222
|
+
if (name) params.name = Array.isArray(name) ? name : [name];
|
|
223
|
+
if (spanKind)
|
|
231
224
|
params.span_kind = Array.isArray(spanKind) ? spanKind : [spanKind];
|
|
232
|
-
}
|
|
233
|
-
|
|
234
225
|
if (statusCode) {
|
|
235
226
|
params.status_code = Array.isArray(statusCode) ? statusCode : [statusCode];
|
|
236
227
|
}
|
|
228
|
+
if (attributeFilters) params.attribute = attributeFilters;
|
|
229
|
+
return params;
|
|
230
|
+
}
|
|
237
231
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
232
|
+
export async function getSpans({
|
|
233
|
+
client: _client,
|
|
234
|
+
project,
|
|
235
|
+
cursor,
|
|
236
|
+
limit = 100,
|
|
237
|
+
startTime,
|
|
238
|
+
endTime,
|
|
239
|
+
traceIds,
|
|
240
|
+
spanIds,
|
|
241
|
+
parentId,
|
|
242
|
+
name,
|
|
243
|
+
spanKind,
|
|
244
|
+
statusCode,
|
|
245
|
+
attributes,
|
|
246
|
+
}: GetSpansParams): Promise<GetSpansResult> {
|
|
247
|
+
const client = _client ?? createClient();
|
|
248
|
+
const serializedAttributes =
|
|
249
|
+
attributes != null ? serializeAttributes(attributes) : undefined;
|
|
250
|
+
const attributeFilters =
|
|
251
|
+
serializedAttributes != null && serializedAttributes.length > 0
|
|
252
|
+
? serializedAttributes
|
|
253
|
+
: undefined;
|
|
254
|
+
await ensureSpanFilterCapabilities({
|
|
255
|
+
client,
|
|
256
|
+
traceIds,
|
|
257
|
+
spanIds,
|
|
258
|
+
name,
|
|
259
|
+
spanKind,
|
|
260
|
+
statusCode,
|
|
261
|
+
attributeFilters,
|
|
262
|
+
});
|
|
263
|
+
const projectIdentifier = resolveProjectIdentifier(project);
|
|
264
|
+
const params = buildSpansQuery({
|
|
265
|
+
cursor,
|
|
266
|
+
limit,
|
|
267
|
+
startTime,
|
|
268
|
+
endTime,
|
|
269
|
+
traceIds,
|
|
270
|
+
spanIds,
|
|
271
|
+
parentId,
|
|
272
|
+
name,
|
|
273
|
+
spanKind,
|
|
274
|
+
statusCode,
|
|
275
|
+
attributeFilters,
|
|
276
|
+
});
|
|
241
277
|
|
|
242
278
|
const { data, error } = await client.GET(
|
|
243
279
|
"/v1/projects/{project_identifier}/spans",
|
|
@@ -220,31 +220,33 @@ function buildLinks(
|
|
|
220
220
|
];
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
suite.trackingDisabledReason = tracking.reason;
|
|
235
|
-
suite.tracer = createNoOpProvider().getTracer("no-op");
|
|
236
|
-
suite.evaluatorTracer = suite.tracer;
|
|
237
|
-
return;
|
|
223
|
+
function disableSuiteTracking({
|
|
224
|
+
suite,
|
|
225
|
+
error,
|
|
226
|
+
}: {
|
|
227
|
+
suite: SuiteState;
|
|
228
|
+
error?: unknown;
|
|
229
|
+
}): void {
|
|
230
|
+
suite.trackingDisabled = true;
|
|
231
|
+
if (error !== undefined) {
|
|
232
|
+
suite.setupError =
|
|
233
|
+
error instanceof Error ? error : new Error(String(error));
|
|
238
234
|
}
|
|
235
|
+
suite.tracer = createNoOpProvider().getTracer("no-op");
|
|
236
|
+
suite.evaluatorTracer = suite.tracer;
|
|
237
|
+
}
|
|
239
238
|
|
|
240
|
-
|
|
241
|
-
suite
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
239
|
+
async function createSuiteDataset({
|
|
240
|
+
suite,
|
|
241
|
+
client,
|
|
242
|
+
datasetName,
|
|
243
|
+
description,
|
|
244
|
+
}: {
|
|
245
|
+
suite: SuiteState;
|
|
246
|
+
client: PhoenixClient;
|
|
247
|
+
datasetName: string;
|
|
248
|
+
description: string;
|
|
249
|
+
}): Promise<string | null> {
|
|
248
250
|
const examples = Array.from(suite.registeredExamples.values()).map(
|
|
249
251
|
(registered) => ({
|
|
250
252
|
id: registered.params.id ?? null,
|
|
@@ -254,8 +256,6 @@ export async function initializeSuite(suite: SuiteState): Promise<void> {
|
|
|
254
256
|
splits: registered.params.splits,
|
|
255
257
|
})
|
|
256
258
|
);
|
|
257
|
-
|
|
258
|
-
let datasetId: string;
|
|
259
259
|
try {
|
|
260
260
|
const created = await createDataset({
|
|
261
261
|
client,
|
|
@@ -263,67 +263,81 @@ export async function initializeSuite(suite: SuiteState): Promise<void> {
|
|
|
263
263
|
description,
|
|
264
264
|
examples,
|
|
265
265
|
});
|
|
266
|
-
|
|
267
|
-
} catch (
|
|
268
|
-
suite
|
|
269
|
-
|
|
270
|
-
suite.tracer = createNoOpProvider().getTracer("no-op");
|
|
271
|
-
suite.evaluatorTracer = suite.tracer;
|
|
272
|
-
return;
|
|
266
|
+
return created.datasetId;
|
|
267
|
+
} catch (error) {
|
|
268
|
+
disableSuiteTracking({ suite, error });
|
|
269
|
+
return null;
|
|
273
270
|
}
|
|
274
|
-
|
|
271
|
+
}
|
|
275
272
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
273
|
+
async function resolveSuiteExampleIds({
|
|
274
|
+
suite,
|
|
275
|
+
client,
|
|
276
|
+
datasetId,
|
|
277
|
+
}: {
|
|
278
|
+
suite: SuiteState;
|
|
279
|
+
client: PhoenixClient;
|
|
280
|
+
datasetId: string;
|
|
281
|
+
}): Promise<void> {
|
|
280
282
|
try {
|
|
281
283
|
const { data: response } = await client.GET("/v1/datasets/{id}/examples", {
|
|
282
284
|
params: { path: { id: datasetId } },
|
|
283
285
|
});
|
|
284
286
|
const fetched = response?.data?.examples ?? [];
|
|
285
|
-
|
|
286
287
|
const idToTestName = new Map<string, string>();
|
|
287
288
|
const inputKeyToTestNames = new Map<string, string[]>();
|
|
288
289
|
for (const [testName, registered] of suite.registeredExamples.entries()) {
|
|
289
290
|
if (registered.params.id) {
|
|
290
291
|
idToTestName.set(registered.params.id, testName);
|
|
291
|
-
|
|
292
|
+
} else {
|
|
293
|
+
const key = stableKey(registered.params.input);
|
|
294
|
+
inputKeyToTestNames.set(key, [
|
|
295
|
+
...(inputKeyToTestNames.get(key) ?? []),
|
|
296
|
+
testName,
|
|
297
|
+
]);
|
|
292
298
|
}
|
|
293
|
-
const key = stableKey(registered.params.input);
|
|
294
|
-
const arr = inputKeyToTestNames.get(key) ?? [];
|
|
295
|
-
arr.push(testName);
|
|
296
|
-
inputKeyToTestNames.set(key, arr);
|
|
297
299
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
nodeId: ex.node_id,
|
|
300
|
+
for (const example of fetched) {
|
|
301
|
+
const testName = idToTestName.get(example.id);
|
|
302
|
+
if (testName) {
|
|
303
|
+
suite.exampleIdsByTest.set(testName, {
|
|
304
|
+
exampleId: example.id,
|
|
305
|
+
nodeId: example.node_id,
|
|
305
306
|
});
|
|
306
|
-
idToTestName.delete(
|
|
307
|
+
idToTestName.delete(example.id);
|
|
307
308
|
continue;
|
|
308
309
|
}
|
|
309
|
-
const queue = inputKeyToTestNames.get(stableKey(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
suite.exampleIdsByTest.set(
|
|
313
|
-
exampleId:
|
|
314
|
-
nodeId:
|
|
310
|
+
const queue = inputKeyToTestNames.get(stableKey(example.input));
|
|
311
|
+
const matchedTestName = queue?.shift();
|
|
312
|
+
if (matchedTestName) {
|
|
313
|
+
suite.exampleIdsByTest.set(matchedTestName, {
|
|
314
|
+
exampleId: example.id,
|
|
315
|
+
nodeId: example.node_id,
|
|
315
316
|
});
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
319
|
} catch {
|
|
319
|
-
//
|
|
320
|
+
// Runs can still be logged without resolved example IDs.
|
|
320
321
|
}
|
|
322
|
+
}
|
|
321
323
|
|
|
324
|
+
async function createSuiteExperiment({
|
|
325
|
+
suite,
|
|
326
|
+
client,
|
|
327
|
+
datasetId,
|
|
328
|
+
datasetName,
|
|
329
|
+
description,
|
|
330
|
+
}: {
|
|
331
|
+
suite: SuiteState;
|
|
332
|
+
client: PhoenixClient;
|
|
333
|
+
datasetId: string;
|
|
334
|
+
datasetName: string;
|
|
335
|
+
description: string;
|
|
336
|
+
}): Promise<boolean> {
|
|
322
337
|
const projectName = `${datasetName}-${new Date().toISOString()}`;
|
|
323
338
|
suite.projectName = projectName;
|
|
324
|
-
|
|
325
339
|
try {
|
|
326
|
-
const
|
|
340
|
+
const response = await client
|
|
327
341
|
.POST("/v1/datasets/{dataset_id}/experiments", {
|
|
328
342
|
params: { path: { dataset_id: datasetId } },
|
|
329
343
|
body: {
|
|
@@ -334,37 +348,46 @@ export async function initializeSuite(suite: SuiteState): Promise<void> {
|
|
|
334
348
|
repetitions: Math.max(1, suite.maxRepetitions ?? 1),
|
|
335
349
|
},
|
|
336
350
|
})
|
|
337
|
-
.then((
|
|
338
|
-
if (!
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
suite.setupError = err instanceof Error ? err : new Error(String(err));
|
|
346
|
-
suite.tracer = createNoOpProvider().getTracer("no-op");
|
|
347
|
-
suite.evaluatorTracer = suite.tracer;
|
|
348
|
-
return;
|
|
351
|
+
.then((result) => result.data?.data);
|
|
352
|
+
if (!response) throw new Error("Failed to create experiment");
|
|
353
|
+
suite.experimentId = response.id;
|
|
354
|
+
suite.projectName = response.project_name ?? projectName;
|
|
355
|
+
return true;
|
|
356
|
+
} catch (error) {
|
|
357
|
+
disableSuiteTracking({ suite, error });
|
|
358
|
+
return false;
|
|
349
359
|
}
|
|
360
|
+
}
|
|
350
361
|
|
|
362
|
+
function setupSuiteTracer({
|
|
363
|
+
suite,
|
|
364
|
+
client,
|
|
365
|
+
}: {
|
|
366
|
+
suite: SuiteState;
|
|
367
|
+
client: PhoenixClient;
|
|
368
|
+
}): boolean {
|
|
351
369
|
const baseUrl = client.config.baseUrl;
|
|
352
370
|
if (!baseUrl) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
return;
|
|
371
|
+
disableSuiteTracking({
|
|
372
|
+
suite,
|
|
373
|
+
error: new Error(
|
|
374
|
+
"Phoenix base URL not found. Set PHOENIX_ENDPOINT (or PHOENIX_COLLECTOR_ENDPOINT) or pass baseUrl on the client."
|
|
375
|
+
),
|
|
376
|
+
});
|
|
377
|
+
return false;
|
|
360
378
|
}
|
|
361
|
-
|
|
362
379
|
maybeWarnHttpScheme(baseUrl, client.config.headers);
|
|
363
|
-
|
|
364
|
-
|
|
380
|
+
const projectName = suite.projectName;
|
|
381
|
+
if (!projectName) {
|
|
382
|
+
disableSuiteTracking({
|
|
383
|
+
suite,
|
|
384
|
+
error: new Error("Experiment project name is missing."),
|
|
385
|
+
});
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
365
388
|
try {
|
|
366
|
-
provider = register({
|
|
367
|
-
projectName
|
|
389
|
+
const provider = register({
|
|
390
|
+
projectName,
|
|
368
391
|
url: getTraceExportUrl(client.config),
|
|
369
392
|
headers: client.config.headers
|
|
370
393
|
? toObjectHeaders(client.config.headers)
|
|
@@ -374,18 +397,59 @@ export async function initializeSuite(suite: SuiteState): Promise<void> {
|
|
|
374
397
|
});
|
|
375
398
|
suite.tracerProvider = provider;
|
|
376
399
|
suite.globalRegistration = attachGlobalTracerProvider(provider);
|
|
377
|
-
|
|
400
|
+
suite.tracer = provider.getTracer(projectName);
|
|
401
|
+
suite.evaluatorTracer = provider.getTracer(`${projectName}-evaluators`);
|
|
402
|
+
return true;
|
|
403
|
+
} catch (error) {
|
|
404
|
+
disableSuiteTracking({ suite, error });
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Initialize the suite: upload the dataset, create the experiment, and
|
|
411
|
+
* register the OpenInference tracer.
|
|
412
|
+
*
|
|
413
|
+
* If tracing is disabled (no Phoenix env vars, or PHOENIX_TEST_TRACKING=false),
|
|
414
|
+
* this populates a no-op tracer and exits without making any network calls.
|
|
415
|
+
*/
|
|
416
|
+
export async function initializeSuite(suite: SuiteState): Promise<void> {
|
|
417
|
+
const tracking = isTrackingEnabled(suite);
|
|
418
|
+
if (!tracking.enabled) {
|
|
378
419
|
suite.trackingDisabled = true;
|
|
379
|
-
suite.
|
|
420
|
+
suite.trackingDisabledReason = tracking.reason;
|
|
380
421
|
suite.tracer = createNoOpProvider().getTracer("no-op");
|
|
381
422
|
suite.evaluatorTracer = suite.tracer;
|
|
382
423
|
return;
|
|
383
424
|
}
|
|
384
|
-
suite.tracer = provider.getTracer(suite.projectName);
|
|
385
|
-
suite.evaluatorTracer = provider.getTracer(`${suite.projectName}-evaluators`);
|
|
386
425
|
|
|
387
|
-
|
|
388
|
-
|
|
426
|
+
const client = suite.config.client ?? createClient();
|
|
427
|
+
suite.client = client;
|
|
428
|
+
|
|
429
|
+
const datasetName = suite.config.datasetName ?? suite.name;
|
|
430
|
+
const description =
|
|
431
|
+
suite.config.description ??
|
|
432
|
+
`Phoenix test dataset auto-generated from ${suite.name}`;
|
|
433
|
+
|
|
434
|
+
const datasetId = await createSuiteDataset({
|
|
435
|
+
suite,
|
|
436
|
+
client,
|
|
437
|
+
datasetName,
|
|
438
|
+
description,
|
|
439
|
+
});
|
|
440
|
+
if (!datasetId) return;
|
|
441
|
+
suite.datasetId = datasetId;
|
|
442
|
+
await resolveSuiteExampleIds({ suite, client, datasetId });
|
|
443
|
+
const hasExperiment = await createSuiteExperiment({
|
|
444
|
+
suite,
|
|
445
|
+
client,
|
|
446
|
+
datasetId,
|
|
447
|
+
datasetName,
|
|
448
|
+
description,
|
|
449
|
+
});
|
|
450
|
+
if (!hasExperiment || !setupSuiteTracer({ suite, client })) return;
|
|
451
|
+
if (suite.experimentId) {
|
|
452
|
+
suite.links = buildLinks(client, datasetId, suite.experimentId);
|
|
389
453
|
}
|
|
390
454
|
}
|
|
391
455
|
|
package/src/types/prompts.ts
CHANGED
package/src/types/sessions.ts
CHANGED
|
@@ -24,6 +24,12 @@ export interface Session extends Node {
|
|
|
24
24
|
startTime: string;
|
|
25
25
|
/** ISO 8601 timestamp of when the last trace in the session ended */
|
|
26
26
|
endTime: string;
|
|
27
|
+
/** Cumulative prompt token count across all spans in the session */
|
|
28
|
+
tokenCountPrompt?: number;
|
|
29
|
+
/** Cumulative completion token count across all spans in the session */
|
|
30
|
+
tokenCountCompletion?: number;
|
|
31
|
+
/** Cumulative total token count across all spans in the session */
|
|
32
|
+
tokenCountTotal?: number;
|
|
27
33
|
/** The traces that belong to this session */
|
|
28
34
|
traces: SessionTrace[];
|
|
29
35
|
}
|