@arizeai/phoenix-client 7.12.0 → 7.13.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/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 projects, prompts, datasets, experiments, spans, sessions, traces, users, 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, secrets, users, and CI-friendly dataset-backed eval tests.
7
7
 
8
8
  ## Install
9
9
 
@@ -44,6 +44,7 @@ That gives the agent version-matched docs plus the exact implementation and gene
44
44
  | `@arizeai/phoenix-client/spans` | Span search, notes, and span/document annotations |
45
45
  | `@arizeai/phoenix-client/sessions` | Session listing, retrieval, and session annotations |
46
46
  | `@arizeai/phoenix-client/traces` | Project trace retrieval, transfers, and trace annotations |
47
+ | `@arizeai/phoenix-client/secrets` | Atomic secret creation, rotation, and deletion |
47
48
  | `@arizeai/phoenix-client/users` | Current authenticated user retrieval |
48
49
  | `@arizeai/phoenix-client/vitest` | Vitest entrypoint for dataset-backed eval tests |
49
50
  | `@arizeai/phoenix-client/vitest/reporter` | Vitest reporter for Phoenix eval summaries |
@@ -164,6 +165,7 @@ Prefer this layer when:
164
165
  - [Annotations](./annotations) — annotation concepts, then [Span](./span-annotations), [Document](./document-annotations), and [Session](./session-annotations) annotations for detailed usage
165
166
  - [CI Eval Tests](./ci-evals) — Vitest/Jest eval suites backed by Phoenix datasets and experiments
166
167
  - [Spans](./spans), [Sessions](./sessions), [Traces](./traces), [Users](./users) — retrieval and maintenance
168
+ - [Secrets](./secrets) — encrypted provider credential management
167
169
 
168
170
  <section className="hidden" data-agent-context="source-map" aria-label="Source map">
169
171
  <h2>Source Map</h2>
@@ -180,6 +182,7 @@ Prefer this layer when:
180
182
  <li><code>src/spans/</code></li>
181
183
  <li><code>src/sessions/</code></li>
182
184
  <li><code>src/traces/</code></li>
185
+ <li><code>src/secrets/</code></li>
183
186
  <li><code>src/users/</code></li>
184
187
  <li><code>src/vitest/</code></li>
185
188
  <li><code>src/jest/</code></li>
@@ -0,0 +1,68 @@
1
+ ---
2
+ title: "Secrets"
3
+ description: "Atomically manage encrypted provider credentials with the Phoenix TypeScript client"
4
+ ---
5
+
6
+ Use `upsertOrDeleteSecrets` from the `@arizeai/phoenix-client/secrets` entrypoint to create, rotate, or delete encrypted provider credentials in one atomic request.
7
+
8
+ <Warning>
9
+ Managing secrets requires an administrator when Phoenix authentication is enabled. Do not log the request batch or retain its values outside your credential store.
10
+ </Warning>
11
+
12
+ ## Create, Update, And Delete Secrets
13
+
14
+ Each batch entry has a `key` and a required `value`:
15
+
16
+ - A string value creates or updates the secret.
17
+ - `null` deletes the secret.
18
+ - When a key occurs more than once, its last occurrence wins.
19
+
20
+ ```ts
21
+ import { upsertOrDeleteSecrets } from "@arizeai/phoenix-client/secrets";
22
+
23
+ const apiKey = process.env.OPENAI_API_KEY;
24
+ if (!apiKey) throw new Error("OPENAI_API_KEY is required");
25
+
26
+ const result = await upsertOrDeleteSecrets({
27
+ secrets: [
28
+ { key: "OPENAI_API_KEY", value: apiKey },
29
+ { key: "OLD_PROVIDER_API_KEY", value: null },
30
+ ],
31
+ });
32
+
33
+ console.log(result.upsertedKeys);
34
+ console.log(result.deletedKeys);
35
+ ```
36
+
37
+ The operation returns only `upsertedKeys` and `deletedKeys`. Submitted secret values are never returned or added to helper error messages.
38
+
39
+ ## Use An Explicit Client
40
+
41
+ Pass `client` when you need to target a particular Phoenix instance. Otherwise, the helper creates a client from the standard Phoenix environment configuration.
42
+
43
+ ```ts
44
+ import { createClient } from "@arizeai/phoenix-client";
45
+ import { upsertOrDeleteSecrets } from "@arizeai/phoenix-client/secrets";
46
+
47
+ const apiKey = process.env.OPENAI_API_KEY;
48
+ if (!apiKey) throw new Error("OPENAI_API_KEY is required");
49
+
50
+ const client = createClient({
51
+ options: { baseUrl: "https://phoenix.example.com" },
52
+ });
53
+
54
+ await upsertOrDeleteSecrets({
55
+ client,
56
+ secrets: [{ key: "OPENAI_API_KEY", value: apiKey }],
57
+ });
58
+ ```
59
+
60
+ <section className="hidden" data-agent-context="source-map" aria-label="Source map">
61
+ <h2>Source Map</h2>
62
+ <ul>
63
+ <li><code>src/secrets/index.ts</code></li>
64
+ <li><code>src/secrets/upsertOrDeleteSecrets.ts</code></li>
65
+ <li><code>src/client.ts</code></li>
66
+ <li><code>src/__generated__/api/v1.ts</code></li>
67
+ </ul>
68
+ </section>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arizeai/phoenix-client",
3
- "version": "7.12.0",
3
+ "version": "7.13.0",
4
4
  "description": "A client for the Phoenix API",
5
5
  "keywords": [
6
6
  "arize",
@@ -53,6 +53,10 @@
53
53
  "import": "./dist/esm/sessions/index.js",
54
54
  "require": "./dist/src/sessions/index.js"
55
55
  },
56
+ "./secrets": {
57
+ "import": "./dist/esm/secrets/index.js",
58
+ "require": "./dist/src/secrets/index.js"
59
+ },
56
60
  "./projects": {
57
61
  "import": "./dist/esm/projects/index.js",
58
62
  "require": "./dist/src/projects/index.js"
@@ -115,7 +119,7 @@
115
119
  "@ai-sdk/openai": "^4.0.71",
116
120
  "@ai-sdk/otel": "^1.0.107",
117
121
  "@anthropic-ai/sdk": "^0.111.0",
118
- "@arizeai/phoenix-evals": "2.5.0",
122
+ "@arizeai/phoenix-evals": "2.6.0",
119
123
  "@arizeai/phoenix-testing": "0.0.0",
120
124
  "@opentelemetry/api": "^1.9.1",
121
125
  "@opentelemetry/sdk-trace-node": "^2.11.0",
@@ -0,0 +1 @@
1
+ export * from "./upsertOrDeleteSecrets";
@@ -0,0 +1,87 @@
1
+ import { createClient } from "../client";
2
+ import type { ClientFn } from "../types/core";
3
+
4
+ /**
5
+ * A secret to create, update, or delete.
6
+ */
7
+ export interface SecretInput {
8
+ /** The environment-style key used to identify the secret. */
9
+ key: string;
10
+ /** A value to create or update, or `null` to delete the key. */
11
+ value: string | null;
12
+ }
13
+
14
+ /**
15
+ * Parameters for atomically updating secrets.
16
+ */
17
+ export interface UpsertOrDeleteSecretsParams extends ClientFn {
18
+ /**
19
+ * Ordered secret updates. When a key occurs more than once, the server
20
+ * applies only its last occurrence.
21
+ */
22
+ secrets: SecretInput[];
23
+ }
24
+
25
+ /**
26
+ * The names of the keys changed by a secrets update.
27
+ *
28
+ * Secret values are intentionally excluded.
29
+ */
30
+ export interface UpsertOrDeleteSecretsResult {
31
+ /** Keys that were created or updated. */
32
+ upsertedKeys: string[];
33
+ /** Keys that were deleted. */
34
+ deletedKeys: string[];
35
+ }
36
+
37
+ /**
38
+ * Atomically create, update, or delete a batch of Phoenix secrets.
39
+ *
40
+ * A non-null value creates or updates a secret, while `null` deletes it.
41
+ * Duplicate keys use the last occurrence in the batch. The result contains
42
+ * key names only; submitted values are never returned or logged.
43
+ *
44
+ * @param params - The secrets update.
45
+ * @param params.client - Optional Phoenix client instance.
46
+ * @param params.secrets - Ordered key/value-or-null updates.
47
+ * @returns The names of the keys that were upserted and deleted.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * import { upsertOrDeleteSecrets } from "@arizeai/phoenix-client/secrets";
52
+ *
53
+ * const apiKey = process.env.OPENAI_API_KEY;
54
+ * if (!apiKey) throw new Error("OPENAI_API_KEY is required");
55
+ *
56
+ * const result = await upsertOrDeleteSecrets({
57
+ * secrets: [
58
+ * { key: "OPENAI_API_KEY", value: apiKey },
59
+ * { key: "OLD_PROVIDER_API_KEY", value: null },
60
+ * ],
61
+ * });
62
+ * ```
63
+ */
64
+ export async function upsertOrDeleteSecrets({
65
+ client: _client,
66
+ secrets,
67
+ }: UpsertOrDeleteSecretsParams): Promise<UpsertOrDeleteSecretsResult> {
68
+ const client = _client ?? createClient();
69
+ const { data, error } = await client.PUT("/v1/secrets", {
70
+ body: { secrets },
71
+ });
72
+
73
+ // Do not include the server error payload here: validation responses can be
74
+ // influenced by submitted data, which must never enter helper error text.
75
+ if (error) {
76
+ throw new Error("Failed to upsert or delete secrets");
77
+ }
78
+
79
+ if (!data?.data) {
80
+ throw new Error("Failed to upsert or delete secrets: no data returned");
81
+ }
82
+
83
+ return {
84
+ upsertedKeys: data.data.upserted_keys,
85
+ deletedKeys: data.data.deleted_keys,
86
+ };
87
+ }