UNPKG

@arizeai/phoenix-client

Version:
124 lines 4.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSessionTurns = getSessionTurns; const openinference_semantic_conventions_1 = require("@arizeai/openinference-semantic-conventions"); const client_1 = require("../client"); const getSpans_1 = require("../spans/getSpans"); const getSession_1 = require("./getSession"); const MAX_TRACE_IDS_PER_BATCH = 50; /** * Get the turns (root span I/O) for a session. * * Returns input/output extracted from root spans for each trace, along with * the full root span. Turns are ordered by trace start_time. * * **Note:** A "turn" is derived from a trace's root span. For input/output to appear, * the root span must have `input.value` and `output.value` attributes set * (per OpenInference semantic conventions). This typically requires instrumentation * that records these attributes on the top-level span. * * @experimental this function is experimental and may change in the future * * @example * ```ts * import { getSessionTurns } from "@arizeai/phoenix-client/sessions"; * * const turns = await getSessionTurns({ sessionId: "my-session" }); * for (const turn of turns) { * console.log(`[${turn.startTime}] Input: ${turn.input?.value}`); * console.log(`[${turn.startTime}] Output: ${turn.output?.value}`); * } * ``` */ async function getSessionTurns({ client: _client, sessionId, }) { const client = _client !== null && _client !== void 0 ? _client : (0, client_1.createClient)(); // getSession already calls ensureSessionsApi internally const session = await (0, getSession_1.getSession)({ client, sessionId }); const traces = session.traces; if (traces.length === 0) { return []; } const projectId = session.projectId; const traceInfo = new Map(traces.map((t) => [t.traceId, t])); const allTraceIds = [...traceInfo.keys()]; // Fetch root spans in batches const rootSpansByTrace = new Map(); for (let i = 0; i < allTraceIds.length; i += MAX_TRACE_IDS_PER_BATCH) { const traceIdBatch = allTraceIds.slice(i, i + MAX_TRACE_IDS_PER_BATCH); const spans = await getAllRootSpansForBatch({ client, projectId, traceIdBatch, }); for (const span of spans) { const traceId = span.context.trace_id; if (!rootSpansByTrace.has(traceId)) { rootSpansByTrace.set(traceId, span); } } } return buildSessionTurns({ allTraceIds, traceInfo, rootSpansByTrace }); } /** * Fetch all root spans for a batch of trace IDs, handling pagination. */ async function getAllRootSpansForBatch({ client, projectId, traceIdBatch, }) { const allSpans = []; let cursor = null; do { const result = await (0, getSpans_1.getSpans)(Object.assign({ client, project: { projectId }, traceIds: traceIdBatch, parentId: null, limit: traceIdBatch.length }, (cursor ? { cursor } : {}))); allSpans.push(...result.spans); cursor = result.nextCursor; } while (cursor != null); return allSpans; } /** * Extract a SessionTurnIO from span attributes for a given prefix. */ function extractIO({ attrs, valueKey, mimeTypeKey, }) { const value = attrs[valueKey]; if (value == null) return undefined; const io = { value: String(value) }; const mimeType = attrs[mimeTypeKey]; if (mimeType != null) { io.mimeType = String(mimeType); } return io; } /** * Build session turns from trace info and root spans, ordered by start_time. */ function buildSessionTurns({ allTraceIds, traceInfo, rootSpansByTrace, }) { var _a; const turns = []; for (const traceId of allTraceIds) { const info = traceInfo.get(traceId); if (!info) continue; const turn = { traceId, startTime: info.startTime, endTime: info.endTime, }; const rootSpan = rootSpansByTrace.get(traceId); if (rootSpan) { turn.rootSpan = rootSpan; const attrs = (_a = rootSpan.attributes) !== null && _a !== void 0 ? _a : {}; turn.input = extractIO({ attrs, valueKey: openinference_semantic_conventions_1.SemanticConventions.INPUT_VALUE, mimeTypeKey: openinference_semantic_conventions_1.SemanticConventions.INPUT_MIME_TYPE, }); turn.output = extractIO({ attrs, valueKey: openinference_semantic_conventions_1.SemanticConventions.OUTPUT_VALUE, mimeTypeKey: openinference_semantic_conventions_1.SemanticConventions.OUTPUT_MIME_TYPE, }); } turns.push(turn); } turns.sort((a, b) => a.startTime.localeCompare(b.startTime)); return turns; } //# sourceMappingURL=getSessionTurns.js.map