@arizeai/phoenix-client 6.5.0 → 6.5.2

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 (63) hide show
  1. package/README.md +194 -0
  2. package/dist/esm/constants/serverRequirements.d.ts +2 -0
  3. package/dist/esm/constants/serverRequirements.d.ts.map +1 -1
  4. package/dist/esm/constants/serverRequirements.js +15 -0
  5. package/dist/esm/constants/serverRequirements.js.map +1 -1
  6. package/dist/esm/prompts/sdks/toAI.d.ts.map +1 -1
  7. package/dist/esm/prompts/sdks/toAI.js +29 -6
  8. package/dist/esm/prompts/sdks/toAI.js.map +1 -1
  9. package/dist/esm/spans/getSpans.d.ts +8 -1
  10. package/dist/esm/spans/getSpans.d.ts.map +1 -1
  11. package/dist/esm/spans/getSpans.js +14 -2
  12. package/dist/esm/spans/getSpans.js.map +1 -1
  13. package/dist/esm/spans/index.d.ts +1 -0
  14. package/dist/esm/spans/index.d.ts.map +1 -1
  15. package/dist/esm/spans/index.js.map +1 -1
  16. package/dist/esm/traces/getTraces.d.ts +78 -0
  17. package/dist/esm/traces/getTraces.d.ts.map +1 -0
  18. package/dist/esm/traces/getTraces.js +96 -0
  19. package/dist/esm/traces/getTraces.js.map +1 -0
  20. package/dist/esm/traces/index.d.ts +2 -0
  21. package/dist/esm/traces/index.d.ts.map +1 -0
  22. package/dist/esm/traces/index.js +2 -0
  23. package/dist/esm/traces/index.js.map +1 -0
  24. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  25. package/dist/esm/types/spans.d.ts +11 -0
  26. package/dist/esm/types/spans.d.ts.map +1 -0
  27. package/dist/esm/types/spans.js +2 -0
  28. package/dist/esm/types/spans.js.map +1 -0
  29. package/dist/src/constants/serverRequirements.d.ts +2 -0
  30. package/dist/src/constants/serverRequirements.d.ts.map +1 -1
  31. package/dist/src/constants/serverRequirements.js +16 -1
  32. package/dist/src/constants/serverRequirements.js.map +1 -1
  33. package/dist/src/prompts/sdks/toAI.d.ts.map +1 -1
  34. package/dist/src/prompts/sdks/toAI.js +28 -7
  35. package/dist/src/prompts/sdks/toAI.js.map +1 -1
  36. package/dist/src/spans/getSpans.d.ts +8 -1
  37. package/dist/src/spans/getSpans.d.ts.map +1 -1
  38. package/dist/src/spans/getSpans.js +13 -1
  39. package/dist/src/spans/getSpans.js.map +1 -1
  40. package/dist/src/spans/index.d.ts +1 -0
  41. package/dist/src/spans/index.d.ts.map +1 -1
  42. package/dist/src/spans/index.js.map +1 -1
  43. package/dist/src/traces/getTraces.d.ts +78 -0
  44. package/dist/src/traces/getTraces.d.ts.map +1 -0
  45. package/dist/src/traces/getTraces.js +100 -0
  46. package/dist/src/traces/getTraces.js.map +1 -0
  47. package/dist/src/traces/index.d.ts +2 -0
  48. package/dist/src/traces/index.d.ts.map +1 -0
  49. package/dist/src/traces/index.js +18 -0
  50. package/dist/src/traces/index.js.map +1 -0
  51. package/dist/src/types/spans.d.ts +11 -0
  52. package/dist/src/types/spans.d.ts.map +1 -0
  53. package/dist/src/types/spans.js +3 -0
  54. package/dist/src/types/spans.js.map +1 -0
  55. package/dist/tsconfig.tsbuildinfo +1 -1
  56. package/package.json +5 -1
  57. package/src/constants/serverRequirements.ts +17 -0
  58. package/src/prompts/sdks/toAI.ts +34 -8
  59. package/src/spans/getSpans.ts +29 -1
  60. package/src/spans/index.ts +1 -0
  61. package/src/traces/getTraces.ts +156 -0
  62. package/src/traces/index.ts +1 -0
  63. package/src/types/spans.ts +12 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arizeai/phoenix-client",
3
- "version": "6.5.0",
3
+ "version": "6.5.2",
4
4
  "description": "A client for the Phoenix API",
5
5
  "keywords": [
6
6
  "arize",
@@ -47,6 +47,10 @@
47
47
  "import": "./dist/esm/sessions/index.js",
48
48
  "require": "./dist/src/sessions/index.js"
49
49
  },
50
+ "./traces": {
51
+ "import": "./dist/esm/traces/index.js",
52
+ "require": "./dist/src/traces/index.js"
53
+ },
50
54
  "./experiments": {
51
55
  "import": "./dist/esm/experiments/index.js",
52
56
  "require": "./dist/src/experiments/index.js"
@@ -61,6 +61,21 @@ export const GET_SPANS_TRACE_IDS: ParameterRequirement = {
61
61
  minServerVersion: [13, 9, 0],
62
62
  };
63
63
 
64
+ export const GET_SPANS_FILTERS: ParameterRequirement = {
65
+ kind: "parameter",
66
+ parameterName: "span_kind",
67
+ parameterLocation: "query",
68
+ route: "GET /v1/projects/{id}/spans",
69
+ minServerVersion: [13, 15, 0],
70
+ };
71
+
72
+ export const LIST_PROJECT_TRACES: RouteRequirement = {
73
+ kind: "route",
74
+ method: "GET",
75
+ path: "/v1/projects/{project_identifier}/traces",
76
+ minServerVersion: [13, 15, 0],
77
+ };
78
+
64
79
  /**
65
80
  * Aggregate list of every known capability requirement.
66
81
  *
@@ -74,4 +89,6 @@ export const ALL_REQUIREMENTS: readonly CapabilityRequirement[] = [
74
89
  LIST_PROJECT_SESSIONS,
75
90
  ANNOTATE_SESSIONS,
76
91
  GET_SPANS_TRACE_IDS,
92
+ GET_SPANS_FILTERS,
93
+ LIST_PROJECT_TRACES,
77
94
  ] as const;
@@ -1,7 +1,12 @@
1
1
  import type { ModelMessage, ToolChoice, ToolSet } from "ai";
2
2
  import invariant from "tiny-invariant";
3
3
 
4
- import { safelyConvertMessageToProvider } from "../../schemas/llm/converters";
4
+ import {
5
+ safelyConvertMessageToProvider,
6
+ safelyConvertToolChoiceToProvider,
7
+ safelyConvertToolDefinitionToProvider,
8
+ } from "../../schemas/llm/converters";
9
+ import { findToolDefinitionName } from "../../schemas/llm/utils";
5
10
  import { formatPromptMessages } from "../../utils/formatPromptMessages";
6
11
  import type { Variables, toSDKParamsBase } from "./types";
7
12
 
@@ -62,19 +67,40 @@ export const toAI = <V extends Variables>({
62
67
  return vercelAIMessage;
63
68
  });
64
69
 
65
- const tools = undefined;
66
- if (prompt.tools?.tools && prompt.tools?.tools.length) {
67
- // eslint-disable-next-line no-console
68
- console.warn(
69
- "Phoenix client does not automatically convert tools to AI SDK tools, please manually convert them."
70
- );
70
+ let tools: ToolSet | undefined;
71
+ if (prompt.tools?.tools && prompt.tools.tools.length > 0) {
72
+ const toolsRecord: Record<string, unknown> = {};
73
+ for (const tool of prompt.tools.tools) {
74
+ const name = findToolDefinitionName(tool);
75
+ invariant(name, "Tool definition name is not valid");
76
+ const converted = safelyConvertToolDefinitionToProvider({
77
+ toolDefinition: tool,
78
+ targetProvider: "VERCEL_AI",
79
+ });
80
+ invariant(converted, "Tool definition is not valid");
81
+ toolsRecord[name] = converted;
82
+ }
83
+ tools =
84
+ Object.keys(toolsRecord).length > 0
85
+ ? (toolsRecord as ToolSet)
86
+ : undefined;
87
+ }
88
+
89
+ let toolChoice: PartialAIParams["toolChoice"];
90
+ if (tools && prompt.tools?.tool_choice) {
91
+ toolChoice =
92
+ safelyConvertToolChoiceToProvider({
93
+ toolChoice: prompt.tools.tool_choice,
94
+ targetProvider: "VERCEL_AI",
95
+ }) ?? undefined;
71
96
  }
72
97
 
73
98
  // combine base and computed params
74
99
  const completionParams: PartialAIParams = {
75
100
  ...baseCompletionParams,
76
101
  messages,
77
- tools,
102
+ ...(tools !== undefined && { tools }),
103
+ ...(toolChoice !== undefined && { toolChoice }),
78
104
  };
79
105
 
80
106
  return completionParams;
@@ -1,9 +1,13 @@
1
1
  import type { operations } from "../__generated__/api/v1";
2
2
  import { createClient } from "../client";
3
- import { GET_SPANS_TRACE_IDS } from "../constants/serverRequirements";
3
+ import {
4
+ GET_SPANS_FILTERS,
5
+ GET_SPANS_TRACE_IDS,
6
+ } from "../constants/serverRequirements";
4
7
  import type { ClientFn } from "../types/core";
5
8
  import type { ProjectIdentifier } from "../types/projects";
6
9
  import { resolveProjectIdentifier } from "../types/projects";
10
+ import type { SpanKindFilter, SpanStatusCode } from "../types/spans";
7
11
  import { ensureServerCapability } from "../utils/serverVersionUtils";
8
12
 
9
13
  /**
@@ -24,6 +28,12 @@ export interface GetSpansParams extends ClientFn {
24
28
  traceIds?: string[] | null;
25
29
  /** Filter by parent span ID. Use `null` or the string `"null"` to get root spans only. */
26
30
  parentId?: string | null;
31
+ /** Filter by span name(s) */
32
+ name?: string | string[] | null;
33
+ /** Filter by span kind(s) (LLM, CHAIN, TOOL, RETRIEVER, etc.) */
34
+ spanKind?: SpanKindFilter | SpanKindFilter[] | null;
35
+ /** Filter by status code(s) (OK, ERROR, UNSET) */
36
+ statusCode?: SpanStatusCode | SpanStatusCode[] | null;
27
37
  }
28
38
 
29
39
  export type GetSpansResponse = operations["getSpans"]["responses"]["200"];
@@ -103,11 +113,17 @@ export async function getSpans({
103
113
  endTime,
104
114
  traceIds,
105
115
  parentId,
116
+ name,
117
+ spanKind,
118
+ statusCode,
106
119
  }: GetSpansParams): Promise<GetSpansResult> {
107
120
  const client = _client ?? createClient();
108
121
  if (traceIds) {
109
122
  await ensureServerCapability({ client, requirement: GET_SPANS_TRACE_IDS });
110
123
  }
124
+ if (name != null || spanKind != null || statusCode != null) {
125
+ await ensureServerCapability({ client, requirement: GET_SPANS_FILTERS });
126
+ }
111
127
  const projectIdentifier = resolveProjectIdentifier(project);
112
128
 
113
129
  const params: NonNullable<operations["getSpans"]["parameters"]["query"]> = {
@@ -135,6 +151,18 @@ export async function getSpans({
135
151
  params.parent_id = parentId === null ? "null" : parentId;
136
152
  }
137
153
 
154
+ if (name) {
155
+ params.name = Array.isArray(name) ? name : [name];
156
+ }
157
+
158
+ if (spanKind) {
159
+ params.span_kind = Array.isArray(spanKind) ? spanKind : [spanKind];
160
+ }
161
+
162
+ if (statusCode) {
163
+ params.status_code = Array.isArray(statusCode) ? statusCode : [statusCode];
164
+ }
165
+
138
166
  const { data, error } = await client.GET(
139
167
  "/v1/projects/{project_identifier}/spans",
140
168
  {
@@ -4,5 +4,6 @@ export * from "./logSpanAnnotations";
4
4
  export * from "./addDocumentAnnotation";
5
5
  export * from "./logDocumentAnnotations";
6
6
  export * from "./getSpans";
7
+ export type { SpanKindFilter, SpanStatusCode } from "../types/spans";
7
8
  export * from "./getSpanAnnotations";
8
9
  export * from "./deleteSpan";
@@ -0,0 +1,156 @@
1
+ import type { operations } from "../__generated__/api/v1";
2
+ import { createClient } from "../client";
3
+ import { LIST_PROJECT_TRACES } from "../constants/serverRequirements";
4
+ import type { ClientFn } from "../types/core";
5
+ import type { ProjectIdentifier } from "../types/projects";
6
+ import { resolveProjectIdentifier } from "../types/projects";
7
+ import { ensureServerCapability } from "../utils/serverVersionUtils";
8
+
9
+ /**
10
+ * Parameters for getting traces from a project.
11
+ */
12
+ export interface GetTracesParams extends ClientFn {
13
+ /** The project to get traces from */
14
+ project: ProjectIdentifier;
15
+ /** Inclusive lower bound time. Must be a valid ISO 8601 string or Date object. */
16
+ startTime?: Date | string | null;
17
+ /** Exclusive upper bound time. Must be a valid ISO 8601 string or Date object. */
18
+ endTime?: Date | string | null;
19
+ /** Sort field */
20
+ sort?: "start_time" | "latency_ms";
21
+ /** Sort direction */
22
+ order?: "asc" | "desc";
23
+ /** Maximum number of traces to return */
24
+ limit?: number;
25
+ /** Pagination cursor (Trace GlobalID) */
26
+ cursor?: string | null;
27
+ /** If true, include full span details for each trace */
28
+ includeSpans?: boolean;
29
+ /** Filter traces by session identifier(s) (session_id strings or GlobalIDs) */
30
+ sessionId?: string | string[] | null;
31
+ }
32
+
33
+ export type GetTracesResponse =
34
+ operations["listProjectTraces"]["responses"]["200"];
35
+
36
+ export type GetTracesResult = {
37
+ traces: GetTracesResponse["content"]["application/json"]["data"];
38
+ nextCursor: GetTracesResponse["content"]["application/json"]["next_cursor"];
39
+ };
40
+
41
+ /**
42
+ * Get traces from a project with filtering and sorting options.
43
+ *
44
+ * This method fetches traces from a project with support for time range filtering,
45
+ * sorting, session filtering, and cursor-based pagination.
46
+ *
47
+ * @requires Phoenix server >= 13.15.0
48
+ *
49
+ * @param params - The parameters to get traces
50
+ * @returns A paginated response containing traces and optional next cursor
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * // Get recent traces from a project
55
+ * const result = await getTraces({
56
+ * client,
57
+ * project: { projectName: "my-project" },
58
+ * limit: 50,
59
+ * });
60
+ *
61
+ * // Get traces in a time range with spans included
62
+ * const result = await getTraces({
63
+ * client,
64
+ * project: { projectName: "my-project" },
65
+ * startTime: new Date("2024-01-01"),
66
+ * endTime: new Date("2024-01-02"),
67
+ * includeSpans: true,
68
+ * });
69
+ *
70
+ * // Paginate through results
71
+ * let cursor: string | undefined;
72
+ * do {
73
+ * const result = await getTraces({
74
+ * client,
75
+ * project: { projectName: "my-project" },
76
+ * cursor,
77
+ * limit: 100,
78
+ * });
79
+ * result.traces.forEach(trace => {
80
+ * console.log(`Trace: ${trace.trace_id}`);
81
+ * });
82
+ * cursor = result.nextCursor || undefined;
83
+ * } while (cursor);
84
+ * ```
85
+ */
86
+ export async function getTraces({
87
+ client: _client,
88
+ project,
89
+ cursor,
90
+ limit = 100,
91
+ startTime,
92
+ endTime,
93
+ sort,
94
+ order,
95
+ includeSpans,
96
+ sessionId,
97
+ }: GetTracesParams): Promise<GetTracesResult> {
98
+ const client = _client ?? createClient();
99
+ await ensureServerCapability({ client, requirement: LIST_PROJECT_TRACES });
100
+ const projectIdentifier = resolveProjectIdentifier(project);
101
+
102
+ const params: NonNullable<
103
+ operations["listProjectTraces"]["parameters"]["query"]
104
+ > = {
105
+ limit,
106
+ };
107
+
108
+ if (cursor) {
109
+ params.cursor = cursor;
110
+ }
111
+
112
+ if (startTime) {
113
+ params.start_time =
114
+ startTime instanceof Date ? startTime.toISOString() : startTime;
115
+ }
116
+
117
+ if (endTime) {
118
+ params.end_time = endTime instanceof Date ? endTime.toISOString() : endTime;
119
+ }
120
+
121
+ if (sort) {
122
+ params.sort = sort;
123
+ }
124
+
125
+ if (order) {
126
+ params.order = order;
127
+ }
128
+
129
+ if (includeSpans) {
130
+ params.include_spans = true;
131
+ }
132
+
133
+ if (sessionId) {
134
+ params.session_identifier = Array.isArray(sessionId)
135
+ ? sessionId
136
+ : [sessionId];
137
+ }
138
+
139
+ const { data, error } = await client.GET(
140
+ "/v1/projects/{project_identifier}/traces",
141
+ {
142
+ params: {
143
+ path: {
144
+ project_identifier: projectIdentifier,
145
+ },
146
+ query: params,
147
+ },
148
+ }
149
+ );
150
+
151
+ if (error) throw error;
152
+ return {
153
+ traces: data?.data ?? [],
154
+ nextCursor: data?.next_cursor ?? null,
155
+ };
156
+ }
@@ -0,0 +1 @@
1
+ export * from "./getTraces";
@@ -0,0 +1,12 @@
1
+ import type { OpenInferenceSpanKind } from "@arizeai/openinference-semantic-conventions";
2
+
3
+ /**
4
+ * Status codes for spans.
5
+ */
6
+ export type SpanStatusCode = "OK" | "ERROR" | "UNSET";
7
+
8
+ /**
9
+ * Span kind filter value. Accepts well-known OpenInference span kinds
10
+ * as well as arbitrary strings for forward-compatibility.
11
+ */
12
+ export type SpanKindFilter = OpenInferenceSpanKind | (string & {});